]> rtime.felk.cvut.cz Git - lisovros/qemu_apohw.git/blob - dump.c
Support for Humusoft MF624 data acquisition card.
[lisovros/qemu_apohw.git] / dump.c
1 /*
2  * QEMU dump
3  *
4  * Copyright Fujitsu, Corp. 2011, 2012
5  *
6  * Authors:
7  *     Wen Congyang <wency@cn.fujitsu.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2 or later.
10  * See the COPYING file in the top-level directory.
11  *
12  */
13
14 #include "qemu-common.h"
15 #include "elf.h"
16 #include "cpu.h"
17 #include "exec/cpu-all.h"
18 #include "exec/hwaddr.h"
19 #include "monitor/monitor.h"
20 #include "sysemu/kvm.h"
21 #include "sysemu/dump.h"
22 #include "sysemu/sysemu.h"
23 #include "sysemu/memory_mapping.h"
24 #include "sysemu/cpus.h"
25 #include "qapi/error.h"
26 #include "qmp-commands.h"
27
28 #include <zlib.h>
29 #ifdef CONFIG_LZO
30 #include <lzo/lzo1x.h>
31 #endif
32 #ifdef CONFIG_SNAPPY
33 #include <snappy-c.h>
34 #endif
35 #ifndef ELF_MACHINE_UNAME
36 #define ELF_MACHINE_UNAME "Unknown"
37 #endif
38
39 uint16_t cpu_to_dump16(DumpState *s, uint16_t val)
40 {
41     if (s->dump_info.d_endian == ELFDATA2LSB) {
42         val = cpu_to_le16(val);
43     } else {
44         val = cpu_to_be16(val);
45     }
46
47     return val;
48 }
49
50 uint32_t cpu_to_dump32(DumpState *s, uint32_t val)
51 {
52     if (s->dump_info.d_endian == ELFDATA2LSB) {
53         val = cpu_to_le32(val);
54     } else {
55         val = cpu_to_be32(val);
56     }
57
58     return val;
59 }
60
61 uint64_t cpu_to_dump64(DumpState *s, uint64_t val)
62 {
63     if (s->dump_info.d_endian == ELFDATA2LSB) {
64         val = cpu_to_le64(val);
65     } else {
66         val = cpu_to_be64(val);
67     }
68
69     return val;
70 }
71
72 static int dump_cleanup(DumpState *s)
73 {
74     int ret = 0;
75
76     guest_phys_blocks_free(&s->guest_phys_blocks);
77     memory_mapping_list_free(&s->list);
78     if (s->fd != -1) {
79         close(s->fd);
80     }
81     if (s->resume) {
82         vm_start();
83     }
84
85     return ret;
86 }
87
88 static void dump_error(DumpState *s, const char *reason)
89 {
90     dump_cleanup(s);
91 }
92
93 static int fd_write_vmcore(const void *buf, size_t size, void *opaque)
94 {
95     DumpState *s = opaque;
96     size_t written_size;
97
98     written_size = qemu_write_full(s->fd, buf, size);
99     if (written_size != size) {
100         return -1;
101     }
102
103     return 0;
104 }
105
106 static int write_elf64_header(DumpState *s)
107 {
108     Elf64_Ehdr elf_header;
109     int ret;
110
111     memset(&elf_header, 0, sizeof(Elf64_Ehdr));
112     memcpy(&elf_header, ELFMAG, SELFMAG);
113     elf_header.e_ident[EI_CLASS] = ELFCLASS64;
114     elf_header.e_ident[EI_DATA] = s->dump_info.d_endian;
115     elf_header.e_ident[EI_VERSION] = EV_CURRENT;
116     elf_header.e_type = cpu_to_dump16(s, ET_CORE);
117     elf_header.e_machine = cpu_to_dump16(s, s->dump_info.d_machine);
118     elf_header.e_version = cpu_to_dump32(s, EV_CURRENT);
119     elf_header.e_ehsize = cpu_to_dump16(s, sizeof(elf_header));
120     elf_header.e_phoff = cpu_to_dump64(s, sizeof(Elf64_Ehdr));
121     elf_header.e_phentsize = cpu_to_dump16(s, sizeof(Elf64_Phdr));
122     elf_header.e_phnum = cpu_to_dump16(s, s->phdr_num);
123     if (s->have_section) {
124         uint64_t shoff = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) * s->sh_info;
125
126         elf_header.e_shoff = cpu_to_dump64(s, shoff);
127         elf_header.e_shentsize = cpu_to_dump16(s, sizeof(Elf64_Shdr));
128         elf_header.e_shnum = cpu_to_dump16(s, 1);
129     }
130
131     ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s);
132     if (ret < 0) {
133         dump_error(s, "dump: failed to write elf header.\n");
134         return -1;
135     }
136
137     return 0;
138 }
139
140 static int write_elf32_header(DumpState *s)
141 {
142     Elf32_Ehdr elf_header;
143     int ret;
144
145     memset(&elf_header, 0, sizeof(Elf32_Ehdr));
146     memcpy(&elf_header, ELFMAG, SELFMAG);
147     elf_header.e_ident[EI_CLASS] = ELFCLASS32;
148     elf_header.e_ident[EI_DATA] = s->dump_info.d_endian;
149     elf_header.e_ident[EI_VERSION] = EV_CURRENT;
150     elf_header.e_type = cpu_to_dump16(s, ET_CORE);
151     elf_header.e_machine = cpu_to_dump16(s, s->dump_info.d_machine);
152     elf_header.e_version = cpu_to_dump32(s, EV_CURRENT);
153     elf_header.e_ehsize = cpu_to_dump16(s, sizeof(elf_header));
154     elf_header.e_phoff = cpu_to_dump32(s, sizeof(Elf32_Ehdr));
155     elf_header.e_phentsize = cpu_to_dump16(s, sizeof(Elf32_Phdr));
156     elf_header.e_phnum = cpu_to_dump16(s, s->phdr_num);
157     if (s->have_section) {
158         uint32_t shoff = sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr) * s->sh_info;
159
160         elf_header.e_shoff = cpu_to_dump32(s, shoff);
161         elf_header.e_shentsize = cpu_to_dump16(s, sizeof(Elf32_Shdr));
162         elf_header.e_shnum = cpu_to_dump16(s, 1);
163     }
164
165     ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s);
166     if (ret < 0) {
167         dump_error(s, "dump: failed to write elf header.\n");
168         return -1;
169     }
170
171     return 0;
172 }
173
174 static int write_elf64_load(DumpState *s, MemoryMapping *memory_mapping,
175                             int phdr_index, hwaddr offset,
176                             hwaddr filesz)
177 {
178     Elf64_Phdr phdr;
179     int ret;
180
181     memset(&phdr, 0, sizeof(Elf64_Phdr));
182     phdr.p_type = cpu_to_dump32(s, PT_LOAD);
183     phdr.p_offset = cpu_to_dump64(s, offset);
184     phdr.p_paddr = cpu_to_dump64(s, memory_mapping->phys_addr);
185     phdr.p_filesz = cpu_to_dump64(s, filesz);
186     phdr.p_memsz = cpu_to_dump64(s, memory_mapping->length);
187     phdr.p_vaddr = cpu_to_dump64(s, memory_mapping->virt_addr);
188
189     assert(memory_mapping->length >= filesz);
190
191     ret = fd_write_vmcore(&phdr, sizeof(Elf64_Phdr), s);
192     if (ret < 0) {
193         dump_error(s, "dump: failed to write program header table.\n");
194         return -1;
195     }
196
197     return 0;
198 }
199
200 static int write_elf32_load(DumpState *s, MemoryMapping *memory_mapping,
201                             int phdr_index, hwaddr offset,
202                             hwaddr filesz)
203 {
204     Elf32_Phdr phdr;
205     int ret;
206
207     memset(&phdr, 0, sizeof(Elf32_Phdr));
208     phdr.p_type = cpu_to_dump32(s, PT_LOAD);
209     phdr.p_offset = cpu_to_dump32(s, offset);
210     phdr.p_paddr = cpu_to_dump32(s, memory_mapping->phys_addr);
211     phdr.p_filesz = cpu_to_dump32(s, filesz);
212     phdr.p_memsz = cpu_to_dump32(s, memory_mapping->length);
213     phdr.p_vaddr = cpu_to_dump32(s, memory_mapping->virt_addr);
214
215     assert(memory_mapping->length >= filesz);
216
217     ret = fd_write_vmcore(&phdr, sizeof(Elf32_Phdr), s);
218     if (ret < 0) {
219         dump_error(s, "dump: failed to write program header table.\n");
220         return -1;
221     }
222
223     return 0;
224 }
225
226 static int write_elf64_note(DumpState *s)
227 {
228     Elf64_Phdr phdr;
229     hwaddr begin = s->memory_offset - s->note_size;
230     int ret;
231
232     memset(&phdr, 0, sizeof(Elf64_Phdr));
233     phdr.p_type = cpu_to_dump32(s, PT_NOTE);
234     phdr.p_offset = cpu_to_dump64(s, begin);
235     phdr.p_paddr = 0;
236     phdr.p_filesz = cpu_to_dump64(s, s->note_size);
237     phdr.p_memsz = cpu_to_dump64(s, s->note_size);
238     phdr.p_vaddr = 0;
239
240     ret = fd_write_vmcore(&phdr, sizeof(Elf64_Phdr), s);
241     if (ret < 0) {
242         dump_error(s, "dump: failed to write program header table.\n");
243         return -1;
244     }
245
246     return 0;
247 }
248
249 static inline int cpu_index(CPUState *cpu)
250 {
251     return cpu->cpu_index + 1;
252 }
253
254 static int write_elf64_notes(WriteCoreDumpFunction f, DumpState *s)
255 {
256     CPUState *cpu;
257     int ret;
258     int id;
259
260     CPU_FOREACH(cpu) {
261         id = cpu_index(cpu);
262         ret = cpu_write_elf64_note(f, cpu, id, s);
263         if (ret < 0) {
264             dump_error(s, "dump: failed to write elf notes.\n");
265             return -1;
266         }
267     }
268
269     CPU_FOREACH(cpu) {
270         ret = cpu_write_elf64_qemunote(f, cpu, s);
271         if (ret < 0) {
272             dump_error(s, "dump: failed to write CPU status.\n");
273             return -1;
274         }
275     }
276
277     return 0;
278 }
279
280 static int write_elf32_note(DumpState *s)
281 {
282     hwaddr begin = s->memory_offset - s->note_size;
283     Elf32_Phdr phdr;
284     int ret;
285
286     memset(&phdr, 0, sizeof(Elf32_Phdr));
287     phdr.p_type = cpu_to_dump32(s, PT_NOTE);
288     phdr.p_offset = cpu_to_dump32(s, begin);
289     phdr.p_paddr = 0;
290     phdr.p_filesz = cpu_to_dump32(s, s->note_size);
291     phdr.p_memsz = cpu_to_dump32(s, s->note_size);
292     phdr.p_vaddr = 0;
293
294     ret = fd_write_vmcore(&phdr, sizeof(Elf32_Phdr), s);
295     if (ret < 0) {
296         dump_error(s, "dump: failed to write program header table.\n");
297         return -1;
298     }
299
300     return 0;
301 }
302
303 static int write_elf32_notes(WriteCoreDumpFunction f, DumpState *s)
304 {
305     CPUState *cpu;
306     int ret;
307     int id;
308
309     CPU_FOREACH(cpu) {
310         id = cpu_index(cpu);
311         ret = cpu_write_elf32_note(f, cpu, id, s);
312         if (ret < 0) {
313             dump_error(s, "dump: failed to write elf notes.\n");
314             return -1;
315         }
316     }
317
318     CPU_FOREACH(cpu) {
319         ret = cpu_write_elf32_qemunote(f, cpu, s);
320         if (ret < 0) {
321             dump_error(s, "dump: failed to write CPU status.\n");
322             return -1;
323         }
324     }
325
326     return 0;
327 }
328
329 static int write_elf_section(DumpState *s, int type)
330 {
331     Elf32_Shdr shdr32;
332     Elf64_Shdr shdr64;
333     int shdr_size;
334     void *shdr;
335     int ret;
336
337     if (type == 0) {
338         shdr_size = sizeof(Elf32_Shdr);
339         memset(&shdr32, 0, shdr_size);
340         shdr32.sh_info = cpu_to_dump32(s, s->sh_info);
341         shdr = &shdr32;
342     } else {
343         shdr_size = sizeof(Elf64_Shdr);
344         memset(&shdr64, 0, shdr_size);
345         shdr64.sh_info = cpu_to_dump32(s, s->sh_info);
346         shdr = &shdr64;
347     }
348
349     ret = fd_write_vmcore(&shdr, shdr_size, s);
350     if (ret < 0) {
351         dump_error(s, "dump: failed to write section header table.\n");
352         return -1;
353     }
354
355     return 0;
356 }
357
358 static int write_data(DumpState *s, void *buf, int length)
359 {
360     int ret;
361
362     ret = fd_write_vmcore(buf, length, s);
363     if (ret < 0) {
364         dump_error(s, "dump: failed to save memory.\n");
365         return -1;
366     }
367
368     return 0;
369 }
370
371 /* write the memroy to vmcore. 1 page per I/O. */
372 static int write_memory(DumpState *s, GuestPhysBlock *block, ram_addr_t start,
373                         int64_t size)
374 {
375     int64_t i;
376     int ret;
377
378     for (i = 0; i < size / TARGET_PAGE_SIZE; i++) {
379         ret = write_data(s, block->host_addr + start + i * TARGET_PAGE_SIZE,
380                          TARGET_PAGE_SIZE);
381         if (ret < 0) {
382             return ret;
383         }
384     }
385
386     if ((size % TARGET_PAGE_SIZE) != 0) {
387         ret = write_data(s, block->host_addr + start + i * TARGET_PAGE_SIZE,
388                          size % TARGET_PAGE_SIZE);
389         if (ret < 0) {
390             return ret;
391         }
392     }
393
394     return 0;
395 }
396
397 /* get the memory's offset and size in the vmcore */
398 static void get_offset_range(hwaddr phys_addr,
399                              ram_addr_t mapping_length,
400                              DumpState *s,
401                              hwaddr *p_offset,
402                              hwaddr *p_filesz)
403 {
404     GuestPhysBlock *block;
405     hwaddr offset = s->memory_offset;
406     int64_t size_in_block, start;
407
408     /* When the memory is not stored into vmcore, offset will be -1 */
409     *p_offset = -1;
410     *p_filesz = 0;
411
412     if (s->has_filter) {
413         if (phys_addr < s->begin || phys_addr >= s->begin + s->length) {
414             return;
415         }
416     }
417
418     QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
419         if (s->has_filter) {
420             if (block->target_start >= s->begin + s->length ||
421                 block->target_end <= s->begin) {
422                 /* This block is out of the range */
423                 continue;
424             }
425
426             if (s->begin <= block->target_start) {
427                 start = block->target_start;
428             } else {
429                 start = s->begin;
430             }
431
432             size_in_block = block->target_end - start;
433             if (s->begin + s->length < block->target_end) {
434                 size_in_block -= block->target_end - (s->begin + s->length);
435             }
436         } else {
437             start = block->target_start;
438             size_in_block = block->target_end - block->target_start;
439         }
440
441         if (phys_addr >= start && phys_addr < start + size_in_block) {
442             *p_offset = phys_addr - start + offset;
443
444             /* The offset range mapped from the vmcore file must not spill over
445              * the GuestPhysBlock, clamp it. The rest of the mapping will be
446              * zero-filled in memory at load time; see
447              * <http://refspecs.linuxbase.org/elf/gabi4+/ch5.pheader.html>.
448              */
449             *p_filesz = phys_addr + mapping_length <= start + size_in_block ?
450                         mapping_length :
451                         size_in_block - (phys_addr - start);
452             return;
453         }
454
455         offset += size_in_block;
456     }
457 }
458
459 static int write_elf_loads(DumpState *s)
460 {
461     hwaddr offset, filesz;
462     MemoryMapping *memory_mapping;
463     uint32_t phdr_index = 1;
464     int ret;
465     uint32_t max_index;
466
467     if (s->have_section) {
468         max_index = s->sh_info;
469     } else {
470         max_index = s->phdr_num;
471     }
472
473     QTAILQ_FOREACH(memory_mapping, &s->list.head, next) {
474         get_offset_range(memory_mapping->phys_addr,
475                          memory_mapping->length,
476                          s, &offset, &filesz);
477         if (s->dump_info.d_class == ELFCLASS64) {
478             ret = write_elf64_load(s, memory_mapping, phdr_index++, offset,
479                                    filesz);
480         } else {
481             ret = write_elf32_load(s, memory_mapping, phdr_index++, offset,
482                                    filesz);
483         }
484
485         if (ret < 0) {
486             return -1;
487         }
488
489         if (phdr_index >= max_index) {
490             break;
491         }
492     }
493
494     return 0;
495 }
496
497 /* write elf header, PT_NOTE and elf note to vmcore. */
498 static int dump_begin(DumpState *s)
499 {
500     int ret;
501
502     /*
503      * the vmcore's format is:
504      *   --------------
505      *   |  elf header |
506      *   --------------
507      *   |  PT_NOTE    |
508      *   --------------
509      *   |  PT_LOAD    |
510      *   --------------
511      *   |  ......     |
512      *   --------------
513      *   |  PT_LOAD    |
514      *   --------------
515      *   |  sec_hdr    |
516      *   --------------
517      *   |  elf note   |
518      *   --------------
519      *   |  memory     |
520      *   --------------
521      *
522      * we only know where the memory is saved after we write elf note into
523      * vmcore.
524      */
525
526     /* write elf header to vmcore */
527     if (s->dump_info.d_class == ELFCLASS64) {
528         ret = write_elf64_header(s);
529     } else {
530         ret = write_elf32_header(s);
531     }
532     if (ret < 0) {
533         return -1;
534     }
535
536     if (s->dump_info.d_class == ELFCLASS64) {
537         /* write PT_NOTE to vmcore */
538         if (write_elf64_note(s) < 0) {
539             return -1;
540         }
541
542         /* write all PT_LOAD to vmcore */
543         if (write_elf_loads(s) < 0) {
544             return -1;
545         }
546
547         /* write section to vmcore */
548         if (s->have_section) {
549             if (write_elf_section(s, 1) < 0) {
550                 return -1;
551             }
552         }
553
554         /* write notes to vmcore */
555         if (write_elf64_notes(fd_write_vmcore, s) < 0) {
556             return -1;
557         }
558
559     } else {
560         /* write PT_NOTE to vmcore */
561         if (write_elf32_note(s) < 0) {
562             return -1;
563         }
564
565         /* write all PT_LOAD to vmcore */
566         if (write_elf_loads(s) < 0) {
567             return -1;
568         }
569
570         /* write section to vmcore */
571         if (s->have_section) {
572             if (write_elf_section(s, 0) < 0) {
573                 return -1;
574             }
575         }
576
577         /* write notes to vmcore */
578         if (write_elf32_notes(fd_write_vmcore, s) < 0) {
579             return -1;
580         }
581     }
582
583     return 0;
584 }
585
586 /* write PT_LOAD to vmcore */
587 static int dump_completed(DumpState *s)
588 {
589     dump_cleanup(s);
590     return 0;
591 }
592
593 static int get_next_block(DumpState *s, GuestPhysBlock *block)
594 {
595     while (1) {
596         block = QTAILQ_NEXT(block, next);
597         if (!block) {
598             /* no more block */
599             return 1;
600         }
601
602         s->start = 0;
603         s->next_block = block;
604         if (s->has_filter) {
605             if (block->target_start >= s->begin + s->length ||
606                 block->target_end <= s->begin) {
607                 /* This block is out of the range */
608                 continue;
609             }
610
611             if (s->begin > block->target_start) {
612                 s->start = s->begin - block->target_start;
613             }
614         }
615
616         return 0;
617     }
618 }
619
620 /* write all memory to vmcore */
621 static int dump_iterate(DumpState *s)
622 {
623     GuestPhysBlock *block;
624     int64_t size;
625     int ret;
626
627     while (1) {
628         block = s->next_block;
629
630         size = block->target_end - block->target_start;
631         if (s->has_filter) {
632             size -= s->start;
633             if (s->begin + s->length < block->target_end) {
634                 size -= block->target_end - (s->begin + s->length);
635             }
636         }
637         ret = write_memory(s, block, s->start, size);
638         if (ret == -1) {
639             return ret;
640         }
641
642         ret = get_next_block(s, block);
643         if (ret == 1) {
644             dump_completed(s);
645             return 0;
646         }
647     }
648 }
649
650 static int create_vmcore(DumpState *s)
651 {
652     int ret;
653
654     ret = dump_begin(s);
655     if (ret < 0) {
656         return -1;
657     }
658
659     ret = dump_iterate(s);
660     if (ret < 0) {
661         return -1;
662     }
663
664     return 0;
665 }
666
667 static int write_start_flat_header(int fd)
668 {
669     MakedumpfileHeader *mh;
670     int ret = 0;
671
672     QEMU_BUILD_BUG_ON(sizeof *mh > MAX_SIZE_MDF_HEADER);
673     mh = g_malloc0(MAX_SIZE_MDF_HEADER);
674
675     memcpy(mh->signature, MAKEDUMPFILE_SIGNATURE,
676            MIN(sizeof mh->signature, sizeof MAKEDUMPFILE_SIGNATURE));
677
678     mh->type = cpu_to_be64(TYPE_FLAT_HEADER);
679     mh->version = cpu_to_be64(VERSION_FLAT_HEADER);
680
681     size_t written_size;
682     written_size = qemu_write_full(fd, mh, MAX_SIZE_MDF_HEADER);
683     if (written_size != MAX_SIZE_MDF_HEADER) {
684         ret = -1;
685     }
686
687     g_free(mh);
688     return ret;
689 }
690
691 static int write_end_flat_header(int fd)
692 {
693     MakedumpfileDataHeader mdh;
694
695     mdh.offset = END_FLAG_FLAT_HEADER;
696     mdh.buf_size = END_FLAG_FLAT_HEADER;
697
698     size_t written_size;
699     written_size = qemu_write_full(fd, &mdh, sizeof(mdh));
700     if (written_size != sizeof(mdh)) {
701         return -1;
702     }
703
704     return 0;
705 }
706
707 static int write_buffer(int fd, off_t offset, const void *buf, size_t size)
708 {
709     size_t written_size;
710     MakedumpfileDataHeader mdh;
711
712     mdh.offset = cpu_to_be64(offset);
713     mdh.buf_size = cpu_to_be64(size);
714
715     written_size = qemu_write_full(fd, &mdh, sizeof(mdh));
716     if (written_size != sizeof(mdh)) {
717         return -1;
718     }
719
720     written_size = qemu_write_full(fd, buf, size);
721     if (written_size != size) {
722         return -1;
723     }
724
725     return 0;
726 }
727
728 static int buf_write_note(const void *buf, size_t size, void *opaque)
729 {
730     DumpState *s = opaque;
731
732     /* note_buf is not enough */
733     if (s->note_buf_offset + size > s->note_size) {
734         return -1;
735     }
736
737     memcpy(s->note_buf + s->note_buf_offset, buf, size);
738
739     s->note_buf_offset += size;
740
741     return 0;
742 }
743
744 /* write common header, sub header and elf note to vmcore */
745 static int create_header32(DumpState *s)
746 {
747     int ret = 0;
748     DiskDumpHeader32 *dh = NULL;
749     KdumpSubHeader32 *kh = NULL;
750     size_t size;
751     uint32_t block_size;
752     uint32_t sub_hdr_size;
753     uint32_t bitmap_blocks;
754     uint32_t status = 0;
755     uint64_t offset_note;
756
757     /* write common header, the version of kdump-compressed format is 6th */
758     size = sizeof(DiskDumpHeader32);
759     dh = g_malloc0(size);
760
761     strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
762     dh->header_version = cpu_to_dump32(s, 6);
763     block_size = TARGET_PAGE_SIZE;
764     dh->block_size = cpu_to_dump32(s, block_size);
765     sub_hdr_size = sizeof(struct KdumpSubHeader32) + s->note_size;
766     sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
767     dh->sub_hdr_size = cpu_to_dump32(s, sub_hdr_size);
768     /* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
769     dh->max_mapnr = cpu_to_dump32(s, MIN(s->max_mapnr, UINT_MAX));
770     dh->nr_cpus = cpu_to_dump32(s, s->nr_cpus);
771     bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
772     dh->bitmap_blocks = cpu_to_dump32(s, bitmap_blocks);
773     strncpy(dh->utsname.machine, ELF_MACHINE_UNAME, sizeof(dh->utsname.machine));
774
775     if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
776         status |= DUMP_DH_COMPRESSED_ZLIB;
777     }
778 #ifdef CONFIG_LZO
779     if (s->flag_compress & DUMP_DH_COMPRESSED_LZO) {
780         status |= DUMP_DH_COMPRESSED_LZO;
781     }
782 #endif
783 #ifdef CONFIG_SNAPPY
784     if (s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) {
785         status |= DUMP_DH_COMPRESSED_SNAPPY;
786     }
787 #endif
788     dh->status = cpu_to_dump32(s, status);
789
790     if (write_buffer(s->fd, 0, dh, size) < 0) {
791         dump_error(s, "dump: failed to write disk dump header.\n");
792         ret = -1;
793         goto out;
794     }
795
796     /* write sub header */
797     size = sizeof(KdumpSubHeader32);
798     kh = g_malloc0(size);
799
800     /* 64bit max_mapnr_64 */
801     kh->max_mapnr_64 = cpu_to_dump64(s, s->max_mapnr);
802     kh->phys_base = cpu_to_dump32(s, PHYS_BASE);
803     kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);
804
805     offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
806     kh->offset_note = cpu_to_dump64(s, offset_note);
807     kh->note_size = cpu_to_dump32(s, s->note_size);
808
809     if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
810                      block_size, kh, size) < 0) {
811         dump_error(s, "dump: failed to write kdump sub header.\n");
812         ret = -1;
813         goto out;
814     }
815
816     /* write note */
817     s->note_buf = g_malloc0(s->note_size);
818     s->note_buf_offset = 0;
819
820     /* use s->note_buf to store notes temporarily */
821     if (write_elf32_notes(buf_write_note, s) < 0) {
822         ret = -1;
823         goto out;
824     }
825
826     if (write_buffer(s->fd, offset_note, s->note_buf,
827                      s->note_size) < 0) {
828         dump_error(s, "dump: failed to write notes");
829         ret = -1;
830         goto out;
831     }
832
833     /* get offset of dump_bitmap */
834     s->offset_dump_bitmap = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size) *
835                              block_size;
836
837     /* get offset of page */
838     s->offset_page = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size + bitmap_blocks) *
839                      block_size;
840
841 out:
842     g_free(dh);
843     g_free(kh);
844     g_free(s->note_buf);
845
846     return ret;
847 }
848
849 /* write common header, sub header and elf note to vmcore */
850 static int create_header64(DumpState *s)
851 {
852     int ret = 0;
853     DiskDumpHeader64 *dh = NULL;
854     KdumpSubHeader64 *kh = NULL;
855     size_t size;
856     uint32_t block_size;
857     uint32_t sub_hdr_size;
858     uint32_t bitmap_blocks;
859     uint32_t status = 0;
860     uint64_t offset_note;
861
862     /* write common header, the version of kdump-compressed format is 6th */
863     size = sizeof(DiskDumpHeader64);
864     dh = g_malloc0(size);
865
866     strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
867     dh->header_version = cpu_to_dump32(s, 6);
868     block_size = TARGET_PAGE_SIZE;
869     dh->block_size = cpu_to_dump32(s, block_size);
870     sub_hdr_size = sizeof(struct KdumpSubHeader64) + s->note_size;
871     sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
872     dh->sub_hdr_size = cpu_to_dump32(s, sub_hdr_size);
873     /* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
874     dh->max_mapnr = cpu_to_dump32(s, MIN(s->max_mapnr, UINT_MAX));
875     dh->nr_cpus = cpu_to_dump32(s, s->nr_cpus);
876     bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
877     dh->bitmap_blocks = cpu_to_dump32(s, bitmap_blocks);
878     strncpy(dh->utsname.machine, ELF_MACHINE_UNAME, sizeof(dh->utsname.machine));
879
880     if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
881         status |= DUMP_DH_COMPRESSED_ZLIB;
882     }
883 #ifdef CONFIG_LZO
884     if (s->flag_compress & DUMP_DH_COMPRESSED_LZO) {
885         status |= DUMP_DH_COMPRESSED_LZO;
886     }
887 #endif
888 #ifdef CONFIG_SNAPPY
889     if (s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) {
890         status |= DUMP_DH_COMPRESSED_SNAPPY;
891     }
892 #endif
893     dh->status = cpu_to_dump32(s, status);
894
895     if (write_buffer(s->fd, 0, dh, size) < 0) {
896         dump_error(s, "dump: failed to write disk dump header.\n");
897         ret = -1;
898         goto out;
899     }
900
901     /* write sub header */
902     size = sizeof(KdumpSubHeader64);
903     kh = g_malloc0(size);
904
905     /* 64bit max_mapnr_64 */
906     kh->max_mapnr_64 = cpu_to_dump64(s, s->max_mapnr);
907     kh->phys_base = cpu_to_dump64(s, PHYS_BASE);
908     kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);
909
910     offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
911     kh->offset_note = cpu_to_dump64(s, offset_note);
912     kh->note_size = cpu_to_dump64(s, s->note_size);
913
914     if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
915                      block_size, kh, size) < 0) {
916         dump_error(s, "dump: failed to write kdump sub header.\n");
917         ret = -1;
918         goto out;
919     }
920
921     /* write note */
922     s->note_buf = g_malloc0(s->note_size);
923     s->note_buf_offset = 0;
924
925     /* use s->note_buf to store notes temporarily */
926     if (write_elf64_notes(buf_write_note, s) < 0) {
927         ret = -1;
928         goto out;
929     }
930
931     if (write_buffer(s->fd, offset_note, s->note_buf,
932                      s->note_size) < 0) {
933         dump_error(s, "dump: failed to write notes");
934         ret = -1;
935         goto out;
936     }
937
938     /* get offset of dump_bitmap */
939     s->offset_dump_bitmap = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size) *
940                              block_size;
941
942     /* get offset of page */
943     s->offset_page = (DISKDUMP_HEADER_BLOCKS + sub_hdr_size + bitmap_blocks) *
944                      block_size;
945
946 out:
947     g_free(dh);
948     g_free(kh);
949     g_free(s->note_buf);
950
951     return ret;
952 }
953
954 static int write_dump_header(DumpState *s)
955 {
956     if (s->dump_info.d_class == ELFCLASS32) {
957         return create_header32(s);
958     } else {
959         return create_header64(s);
960     }
961 }
962
963 /*
964  * set dump_bitmap sequencely. the bit before last_pfn is not allowed to be
965  * rewritten, so if need to set the first bit, set last_pfn and pfn to 0.
966  * set_dump_bitmap will always leave the recently set bit un-sync. And setting
967  * (last bit + sizeof(buf) * 8) to 0 will do flushing the content in buf into
968  * vmcore, ie. synchronizing un-sync bit into vmcore.
969  */
970 static int set_dump_bitmap(uint64_t last_pfn, uint64_t pfn, bool value,
971                            uint8_t *buf, DumpState *s)
972 {
973     off_t old_offset, new_offset;
974     off_t offset_bitmap1, offset_bitmap2;
975     uint32_t byte, bit;
976
977     /* should not set the previous place */
978     assert(last_pfn <= pfn);
979
980     /*
981      * if the bit needed to be set is not cached in buf, flush the data in buf
982      * to vmcore firstly.
983      * making new_offset be bigger than old_offset can also sync remained data
984      * into vmcore.
985      */
986     old_offset = BUFSIZE_BITMAP * (last_pfn / PFN_BUFBITMAP);
987     new_offset = BUFSIZE_BITMAP * (pfn / PFN_BUFBITMAP);
988
989     while (old_offset < new_offset) {
990         /* calculate the offset and write dump_bitmap */
991         offset_bitmap1 = s->offset_dump_bitmap + old_offset;
992         if (write_buffer(s->fd, offset_bitmap1, buf,
993                          BUFSIZE_BITMAP) < 0) {
994             return -1;
995         }
996
997         /* dump level 1 is chosen, so 1st and 2nd bitmap are same */
998         offset_bitmap2 = s->offset_dump_bitmap + s->len_dump_bitmap +
999                          old_offset;
1000         if (write_buffer(s->fd, offset_bitmap2, buf,
1001                          BUFSIZE_BITMAP) < 0) {
1002             return -1;
1003         }
1004
1005         memset(buf, 0, BUFSIZE_BITMAP);
1006         old_offset += BUFSIZE_BITMAP;
1007     }
1008
1009     /* get the exact place of the bit in the buf, and set it */
1010     byte = (pfn % PFN_BUFBITMAP) / CHAR_BIT;
1011     bit = (pfn % PFN_BUFBITMAP) % CHAR_BIT;
1012     if (value) {
1013         buf[byte] |= 1u << bit;
1014     } else {
1015         buf[byte] &= ~(1u << bit);
1016     }
1017
1018     return 0;
1019 }
1020
1021 /*
1022  * exam every page and return the page frame number and the address of the page.
1023  * bufptr can be NULL. note: the blocks here is supposed to reflect guest-phys
1024  * blocks, so block->target_start and block->target_end should be interal
1025  * multiples of the target page size.
1026  */
1027 static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr,
1028                           uint8_t **bufptr, DumpState *s)
1029 {
1030     GuestPhysBlock *block = *blockptr;
1031     hwaddr addr;
1032     uint8_t *buf;
1033
1034     /* block == NULL means the start of the iteration */
1035     if (!block) {
1036         block = QTAILQ_FIRST(&s->guest_phys_blocks.head);
1037         *blockptr = block;
1038         assert((block->target_start & ~TARGET_PAGE_MASK) == 0);
1039         assert((block->target_end & ~TARGET_PAGE_MASK) == 0);
1040         *pfnptr = paddr_to_pfn(block->target_start);
1041         if (bufptr) {
1042             *bufptr = block->host_addr;
1043         }
1044         return true;
1045     }
1046
1047     *pfnptr = *pfnptr + 1;
1048     addr = pfn_to_paddr(*pfnptr);
1049
1050     if ((addr >= block->target_start) &&
1051         (addr + TARGET_PAGE_SIZE <= block->target_end)) {
1052         buf = block->host_addr + (addr - block->target_start);
1053     } else {
1054         /* the next page is in the next block */
1055         block = QTAILQ_NEXT(block, next);
1056         *blockptr = block;
1057         if (!block) {
1058             return false;
1059         }
1060         assert((block->target_start & ~TARGET_PAGE_MASK) == 0);
1061         assert((block->target_end & ~TARGET_PAGE_MASK) == 0);
1062         *pfnptr = paddr_to_pfn(block->target_start);
1063         buf = block->host_addr;
1064     }
1065
1066     if (bufptr) {
1067         *bufptr = buf;
1068     }
1069
1070     return true;
1071 }
1072
1073 static int write_dump_bitmap(DumpState *s)
1074 {
1075     int ret = 0;
1076     uint64_t last_pfn, pfn;
1077     void *dump_bitmap_buf;
1078     size_t num_dumpable;
1079     GuestPhysBlock *block_iter = NULL;
1080
1081     /* dump_bitmap_buf is used to store dump_bitmap temporarily */
1082     dump_bitmap_buf = g_malloc0(BUFSIZE_BITMAP);
1083
1084     num_dumpable = 0;
1085     last_pfn = 0;
1086
1087     /*
1088      * exam memory page by page, and set the bit in dump_bitmap corresponded
1089      * to the existing page.
1090      */
1091     while (get_next_page(&block_iter, &pfn, NULL, s)) {
1092         ret = set_dump_bitmap(last_pfn, pfn, true, dump_bitmap_buf, s);
1093         if (ret < 0) {
1094             dump_error(s, "dump: failed to set dump_bitmap.\n");
1095             ret = -1;
1096             goto out;
1097         }
1098
1099         last_pfn = pfn;
1100         num_dumpable++;
1101     }
1102
1103     /*
1104      * set_dump_bitmap will always leave the recently set bit un-sync. Here we
1105      * set last_pfn + PFN_BUFBITMAP to 0 and those set but un-sync bit will be
1106      * synchronized into vmcore.
1107      */
1108     if (num_dumpable > 0) {
1109         ret = set_dump_bitmap(last_pfn, last_pfn + PFN_BUFBITMAP, false,
1110                               dump_bitmap_buf, s);
1111         if (ret < 0) {
1112             dump_error(s, "dump: failed to sync dump_bitmap.\n");
1113             ret = -1;
1114             goto out;
1115         }
1116     }
1117
1118     /* number of dumpable pages that will be dumped later */
1119     s->num_dumpable = num_dumpable;
1120
1121 out:
1122     g_free(dump_bitmap_buf);
1123
1124     return ret;
1125 }
1126
1127 static void prepare_data_cache(DataCache *data_cache, DumpState *s,
1128                                off_t offset)
1129 {
1130     data_cache->fd = s->fd;
1131     data_cache->data_size = 0;
1132     data_cache->buf_size = BUFSIZE_DATA_CACHE;
1133     data_cache->buf = g_malloc0(BUFSIZE_DATA_CACHE);
1134     data_cache->offset = offset;
1135 }
1136
1137 static int write_cache(DataCache *dc, const void *buf, size_t size,
1138                        bool flag_sync)
1139 {
1140     /*
1141      * dc->buf_size should not be less than size, otherwise dc will never be
1142      * enough
1143      */
1144     assert(size <= dc->buf_size);
1145
1146     /*
1147      * if flag_sync is set, synchronize data in dc->buf into vmcore.
1148      * otherwise check if the space is enough for caching data in buf, if not,
1149      * write the data in dc->buf to dc->fd and reset dc->buf
1150      */
1151     if ((!flag_sync && dc->data_size + size > dc->buf_size) ||
1152         (flag_sync && dc->data_size > 0)) {
1153         if (write_buffer(dc->fd, dc->offset, dc->buf, dc->data_size) < 0) {
1154             return -1;
1155         }
1156
1157         dc->offset += dc->data_size;
1158         dc->data_size = 0;
1159     }
1160
1161     if (!flag_sync) {
1162         memcpy(dc->buf + dc->data_size, buf, size);
1163         dc->data_size += size;
1164     }
1165
1166     return 0;
1167 }
1168
1169 static void free_data_cache(DataCache *data_cache)
1170 {
1171     g_free(data_cache->buf);
1172 }
1173
1174 static size_t get_len_buf_out(size_t page_size, uint32_t flag_compress)
1175 {
1176     switch (flag_compress) {
1177     case DUMP_DH_COMPRESSED_ZLIB:
1178         return compressBound(page_size);
1179
1180     case DUMP_DH_COMPRESSED_LZO:
1181         /*
1182          * LZO will expand incompressible data by a little amount. Please check
1183          * the following URL to see the expansion calculation:
1184          * http://www.oberhumer.com/opensource/lzo/lzofaq.php
1185          */
1186         return page_size + page_size / 16 + 64 + 3;
1187
1188 #ifdef CONFIG_SNAPPY
1189     case DUMP_DH_COMPRESSED_SNAPPY:
1190         return snappy_max_compressed_length(page_size);
1191 #endif
1192     }
1193     return 0;
1194 }
1195
1196 /*
1197  * check if the page is all 0
1198  */
1199 static inline bool is_zero_page(const uint8_t *buf, size_t page_size)
1200 {
1201     return buffer_is_zero(buf, page_size);
1202 }
1203
1204 static int write_dump_pages(DumpState *s)
1205 {
1206     int ret = 0;
1207     DataCache page_desc, page_data;
1208     size_t len_buf_out, size_out;
1209 #ifdef CONFIG_LZO
1210     lzo_bytep wrkmem = NULL;
1211 #endif
1212     uint8_t *buf_out = NULL;
1213     off_t offset_desc, offset_data;
1214     PageDescriptor pd, pd_zero;
1215     uint8_t *buf;
1216     GuestPhysBlock *block_iter = NULL;
1217     uint64_t pfn_iter;
1218
1219     /* get offset of page_desc and page_data in dump file */
1220     offset_desc = s->offset_page;
1221     offset_data = offset_desc + sizeof(PageDescriptor) * s->num_dumpable;
1222
1223     prepare_data_cache(&page_desc, s, offset_desc);
1224     prepare_data_cache(&page_data, s, offset_data);
1225
1226     /* prepare buffer to store compressed data */
1227     len_buf_out = get_len_buf_out(TARGET_PAGE_SIZE, s->flag_compress);
1228     assert(len_buf_out != 0);
1229
1230 #ifdef CONFIG_LZO
1231     wrkmem = g_malloc(LZO1X_1_MEM_COMPRESS);
1232 #endif
1233
1234     buf_out = g_malloc(len_buf_out);
1235
1236     /*
1237      * init zero page's page_desc and page_data, because every zero page
1238      * uses the same page_data
1239      */
1240     pd_zero.size = cpu_to_dump32(s, TARGET_PAGE_SIZE);
1241     pd_zero.flags = cpu_to_dump32(s, 0);
1242     pd_zero.offset = cpu_to_dump64(s, offset_data);
1243     pd_zero.page_flags = cpu_to_dump64(s, 0);
1244     buf = g_malloc0(TARGET_PAGE_SIZE);
1245     ret = write_cache(&page_data, buf, TARGET_PAGE_SIZE, false);
1246     g_free(buf);
1247     if (ret < 0) {
1248         dump_error(s, "dump: failed to write page data(zero page).\n");
1249         goto out;
1250     }
1251
1252     offset_data += TARGET_PAGE_SIZE;
1253
1254     /*
1255      * dump memory to vmcore page by page. zero page will all be resided in the
1256      * first page of page section
1257      */
1258     while (get_next_page(&block_iter, &pfn_iter, &buf, s)) {
1259         /* check zero page */
1260         if (is_zero_page(buf, TARGET_PAGE_SIZE)) {
1261             ret = write_cache(&page_desc, &pd_zero, sizeof(PageDescriptor),
1262                               false);
1263             if (ret < 0) {
1264                 dump_error(s, "dump: failed to write page desc.\n");
1265                 goto out;
1266             }
1267         } else {
1268             /*
1269              * not zero page, then:
1270              * 1. compress the page
1271              * 2. write the compressed page into the cache of page_data
1272              * 3. get page desc of the compressed page and write it into the
1273              *    cache of page_desc
1274              *
1275              * only one compression format will be used here, for
1276              * s->flag_compress is set. But when compression fails to work,
1277              * we fall back to save in plaintext.
1278              */
1279              size_out = len_buf_out;
1280              if ((s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) &&
1281                     (compress2(buf_out, (uLongf *)&size_out, buf,
1282                                TARGET_PAGE_SIZE, Z_BEST_SPEED) == Z_OK) &&
1283                     (size_out < TARGET_PAGE_SIZE)) {
1284                 pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_ZLIB);
1285                 pd.size  = cpu_to_dump32(s, size_out);
1286
1287                 ret = write_cache(&page_data, buf_out, size_out, false);
1288                 if (ret < 0) {
1289                     dump_error(s, "dump: failed to write page data.\n");
1290                     goto out;
1291                 }
1292 #ifdef CONFIG_LZO
1293             } else if ((s->flag_compress & DUMP_DH_COMPRESSED_LZO) &&
1294                     (lzo1x_1_compress(buf, TARGET_PAGE_SIZE, buf_out,
1295                     (lzo_uint *)&size_out, wrkmem) == LZO_E_OK) &&
1296                     (size_out < TARGET_PAGE_SIZE)) {
1297                 pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_LZO);
1298                 pd.size  = cpu_to_dump32(s, size_out);
1299
1300                 ret = write_cache(&page_data, buf_out, size_out, false);
1301                 if (ret < 0) {
1302                     dump_error(s, "dump: failed to write page data.\n");
1303                     goto out;
1304                 }
1305 #endif
1306 #ifdef CONFIG_SNAPPY
1307             } else if ((s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) &&
1308                     (snappy_compress((char *)buf, TARGET_PAGE_SIZE,
1309                     (char *)buf_out, &size_out) == SNAPPY_OK) &&
1310                     (size_out < TARGET_PAGE_SIZE)) {
1311                 pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_SNAPPY);
1312                 pd.size  = cpu_to_dump32(s, size_out);
1313
1314                 ret = write_cache(&page_data, buf_out, size_out, false);
1315                 if (ret < 0) {
1316                     dump_error(s, "dump: failed to write page data.\n");
1317                     goto out;
1318                 }
1319 #endif
1320             } else {
1321                 /*
1322                  * fall back to save in plaintext, size_out should be
1323                  * assigned TARGET_PAGE_SIZE
1324                  */
1325                 pd.flags = cpu_to_dump32(s, 0);
1326                 size_out = TARGET_PAGE_SIZE;
1327                 pd.size = cpu_to_dump32(s, size_out);
1328
1329                 ret = write_cache(&page_data, buf, TARGET_PAGE_SIZE, false);
1330                 if (ret < 0) {
1331                     dump_error(s, "dump: failed to write page data.\n");
1332                     goto out;
1333                 }
1334             }
1335
1336             /* get and write page desc here */
1337             pd.page_flags = cpu_to_dump64(s, 0);
1338             pd.offset = cpu_to_dump64(s, offset_data);
1339             offset_data += size_out;
1340
1341             ret = write_cache(&page_desc, &pd, sizeof(PageDescriptor), false);
1342             if (ret < 0) {
1343                 dump_error(s, "dump: failed to write page desc.\n");
1344                 goto out;
1345             }
1346         }
1347     }
1348
1349     ret = write_cache(&page_desc, NULL, 0, true);
1350     if (ret < 0) {
1351         dump_error(s, "dump: failed to sync cache for page_desc.\n");
1352         goto out;
1353     }
1354     ret = write_cache(&page_data, NULL, 0, true);
1355     if (ret < 0) {
1356         dump_error(s, "dump: failed to sync cache for page_data.\n");
1357         goto out;
1358     }
1359
1360 out:
1361     free_data_cache(&page_desc);
1362     free_data_cache(&page_data);
1363
1364 #ifdef CONFIG_LZO
1365     g_free(wrkmem);
1366 #endif
1367
1368     g_free(buf_out);
1369
1370     return ret;
1371 }
1372
1373 static int create_kdump_vmcore(DumpState *s)
1374 {
1375     int ret;
1376
1377     /*
1378      * the kdump-compressed format is:
1379      *                                               File offset
1380      *  +------------------------------------------+ 0x0
1381      *  |    main header (struct disk_dump_header) |
1382      *  |------------------------------------------+ block 1
1383      *  |    sub header (struct kdump_sub_header)  |
1384      *  |------------------------------------------+ block 2
1385      *  |            1st-dump_bitmap               |
1386      *  |------------------------------------------+ block 2 + X blocks
1387      *  |            2nd-dump_bitmap               | (aligned by block)
1388      *  |------------------------------------------+ block 2 + 2 * X blocks
1389      *  |  page desc for pfn 0 (struct page_desc)  | (aligned by block)
1390      *  |  page desc for pfn 1 (struct page_desc)  |
1391      *  |                    :                     |
1392      *  |------------------------------------------| (not aligned by block)
1393      *  |         page data (pfn 0)                |
1394      *  |         page data (pfn 1)                |
1395      *  |                    :                     |
1396      *  +------------------------------------------+
1397      */
1398
1399     ret = write_start_flat_header(s->fd);
1400     if (ret < 0) {
1401         dump_error(s, "dump: failed to write start flat header.\n");
1402         return -1;
1403     }
1404
1405     ret = write_dump_header(s);
1406     if (ret < 0) {
1407         return -1;
1408     }
1409
1410     ret = write_dump_bitmap(s);
1411     if (ret < 0) {
1412         return -1;
1413     }
1414
1415     ret = write_dump_pages(s);
1416     if (ret < 0) {
1417         return -1;
1418     }
1419
1420     ret = write_end_flat_header(s->fd);
1421     if (ret < 0) {
1422         dump_error(s, "dump: failed to write end flat header.\n");
1423         return -1;
1424     }
1425
1426     dump_completed(s);
1427
1428     return 0;
1429 }
1430
1431 static ram_addr_t get_start_block(DumpState *s)
1432 {
1433     GuestPhysBlock *block;
1434
1435     if (!s->has_filter) {
1436         s->next_block = QTAILQ_FIRST(&s->guest_phys_blocks.head);
1437         return 0;
1438     }
1439
1440     QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
1441         if (block->target_start >= s->begin + s->length ||
1442             block->target_end <= s->begin) {
1443             /* This block is out of the range */
1444             continue;
1445         }
1446
1447         s->next_block = block;
1448         if (s->begin > block->target_start) {
1449             s->start = s->begin - block->target_start;
1450         } else {
1451             s->start = 0;
1452         }
1453         return s->start;
1454     }
1455
1456     return -1;
1457 }
1458
1459 static void get_max_mapnr(DumpState *s)
1460 {
1461     GuestPhysBlock *last_block;
1462
1463     last_block = QTAILQ_LAST(&s->guest_phys_blocks.head, GuestPhysBlockHead);
1464     s->max_mapnr = paddr_to_pfn(last_block->target_end);
1465 }
1466
1467 static int dump_init(DumpState *s, int fd, bool has_format,
1468                      DumpGuestMemoryFormat format, bool paging, bool has_filter,
1469                      int64_t begin, int64_t length, Error **errp)
1470 {
1471     CPUState *cpu;
1472     int nr_cpus;
1473     Error *err = NULL;
1474     int ret;
1475
1476     /* kdump-compressed is conflict with paging and filter */
1477     if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
1478         assert(!paging && !has_filter);
1479     }
1480
1481     if (runstate_is_running()) {
1482         vm_stop(RUN_STATE_SAVE_VM);
1483         s->resume = true;
1484     } else {
1485         s->resume = false;
1486     }
1487
1488     /* If we use KVM, we should synchronize the registers before we get dump
1489      * info or physmap info.
1490      */
1491     cpu_synchronize_all_states();
1492     nr_cpus = 0;
1493     CPU_FOREACH(cpu) {
1494         nr_cpus++;
1495     }
1496
1497     s->fd = fd;
1498     s->has_filter = has_filter;
1499     s->begin = begin;
1500     s->length = length;
1501
1502     guest_phys_blocks_init(&s->guest_phys_blocks);
1503     guest_phys_blocks_append(&s->guest_phys_blocks);
1504
1505     s->start = get_start_block(s);
1506     if (s->start == -1) {
1507         error_set(errp, QERR_INVALID_PARAMETER, "begin");
1508         goto cleanup;
1509     }
1510
1511     /* get dump info: endian, class and architecture.
1512      * If the target architecture is not supported, cpu_get_dump_info() will
1513      * return -1.
1514      */
1515     ret = cpu_get_dump_info(&s->dump_info, &s->guest_phys_blocks);
1516     if (ret < 0) {
1517         error_set(errp, QERR_UNSUPPORTED);
1518         goto cleanup;
1519     }
1520
1521     s->note_size = cpu_get_note_size(s->dump_info.d_class,
1522                                      s->dump_info.d_machine, nr_cpus);
1523     if (s->note_size < 0) {
1524         error_set(errp, QERR_UNSUPPORTED);
1525         goto cleanup;
1526     }
1527
1528     /* get memory mapping */
1529     memory_mapping_list_init(&s->list);
1530     if (paging) {
1531         qemu_get_guest_memory_mapping(&s->list, &s->guest_phys_blocks, &err);
1532         if (err != NULL) {
1533             error_propagate(errp, err);
1534             goto cleanup;
1535         }
1536     } else {
1537         qemu_get_guest_simple_memory_mapping(&s->list, &s->guest_phys_blocks);
1538     }
1539
1540     s->nr_cpus = nr_cpus;
1541
1542     get_max_mapnr(s);
1543
1544     uint64_t tmp;
1545     tmp = DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT), TARGET_PAGE_SIZE);
1546     s->len_dump_bitmap = tmp * TARGET_PAGE_SIZE;
1547
1548     /* init for kdump-compressed format */
1549     if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
1550         switch (format) {
1551         case DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB:
1552             s->flag_compress = DUMP_DH_COMPRESSED_ZLIB;
1553             break;
1554
1555         case DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO:
1556 #ifdef CONFIG_LZO
1557             if (lzo_init() != LZO_E_OK) {
1558                 error_setg(errp, "failed to initialize the LZO library");
1559                 goto cleanup;
1560             }
1561 #endif
1562             s->flag_compress = DUMP_DH_COMPRESSED_LZO;
1563             break;
1564
1565         case DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY:
1566             s->flag_compress = DUMP_DH_COMPRESSED_SNAPPY;
1567             break;
1568
1569         default:
1570             s->flag_compress = 0;
1571         }
1572
1573         return 0;
1574     }
1575
1576     if (s->has_filter) {
1577         memory_mapping_filter(&s->list, s->begin, s->length);
1578     }
1579
1580     /*
1581      * calculate phdr_num
1582      *
1583      * the type of ehdr->e_phnum is uint16_t, so we should avoid overflow
1584      */
1585     s->phdr_num = 1; /* PT_NOTE */
1586     if (s->list.num < UINT16_MAX - 2) {
1587         s->phdr_num += s->list.num;
1588         s->have_section = false;
1589     } else {
1590         s->have_section = true;
1591         s->phdr_num = PN_XNUM;
1592         s->sh_info = 1; /* PT_NOTE */
1593
1594         /* the type of shdr->sh_info is uint32_t, so we should avoid overflow */
1595         if (s->list.num <= UINT32_MAX - 1) {
1596             s->sh_info += s->list.num;
1597         } else {
1598             s->sh_info = UINT32_MAX;
1599         }
1600     }
1601
1602     if (s->dump_info.d_class == ELFCLASS64) {
1603         if (s->have_section) {
1604             s->memory_offset = sizeof(Elf64_Ehdr) +
1605                                sizeof(Elf64_Phdr) * s->sh_info +
1606                                sizeof(Elf64_Shdr) + s->note_size;
1607         } else {
1608             s->memory_offset = sizeof(Elf64_Ehdr) +
1609                                sizeof(Elf64_Phdr) * s->phdr_num + s->note_size;
1610         }
1611     } else {
1612         if (s->have_section) {
1613             s->memory_offset = sizeof(Elf32_Ehdr) +
1614                                sizeof(Elf32_Phdr) * s->sh_info +
1615                                sizeof(Elf32_Shdr) + s->note_size;
1616         } else {
1617             s->memory_offset = sizeof(Elf32_Ehdr) +
1618                                sizeof(Elf32_Phdr) * s->phdr_num + s->note_size;
1619         }
1620     }
1621
1622     return 0;
1623
1624 cleanup:
1625     guest_phys_blocks_free(&s->guest_phys_blocks);
1626
1627     if (s->resume) {
1628         vm_start();
1629     }
1630
1631     return -1;
1632 }
1633
1634 void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
1635                            int64_t begin, bool has_length,
1636                            int64_t length, bool has_format,
1637                            DumpGuestMemoryFormat format, Error **errp)
1638 {
1639     const char *p;
1640     int fd = -1;
1641     DumpState *s;
1642     int ret;
1643
1644     /*
1645      * kdump-compressed format need the whole memory dumped, so paging or
1646      * filter is not supported here.
1647      */
1648     if ((has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) &&
1649         (paging || has_begin || has_length)) {
1650         error_setg(errp, "kdump-compressed format doesn't support paging or "
1651                          "filter");
1652         return;
1653     }
1654     if (has_begin && !has_length) {
1655         error_set(errp, QERR_MISSING_PARAMETER, "length");
1656         return;
1657     }
1658     if (!has_begin && has_length) {
1659         error_set(errp, QERR_MISSING_PARAMETER, "begin");
1660         return;
1661     }
1662
1663     /* check whether lzo/snappy is supported */
1664 #ifndef CONFIG_LZO
1665     if (has_format && format == DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO) {
1666         error_setg(errp, "kdump-lzo is not available now");
1667         return;
1668     }
1669 #endif
1670
1671 #ifndef CONFIG_SNAPPY
1672     if (has_format && format == DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY) {
1673         error_setg(errp, "kdump-snappy is not available now");
1674         return;
1675     }
1676 #endif
1677
1678 #if !defined(WIN32)
1679     if (strstart(file, "fd:", &p)) {
1680         fd = monitor_get_fd(cur_mon, p, errp);
1681         if (fd == -1) {
1682             return;
1683         }
1684     }
1685 #endif
1686
1687     if  (strstart(file, "file:", &p)) {
1688         fd = qemu_open(p, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR);
1689         if (fd < 0) {
1690             error_setg_file_open(errp, errno, p);
1691             return;
1692         }
1693     }
1694
1695     if (fd == -1) {
1696         error_set(errp, QERR_INVALID_PARAMETER, "protocol");
1697         return;
1698     }
1699
1700     s = g_malloc0(sizeof(DumpState));
1701
1702     ret = dump_init(s, fd, has_format, format, paging, has_begin,
1703                     begin, length, errp);
1704     if (ret < 0) {
1705         g_free(s);
1706         return;
1707     }
1708
1709     if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
1710         if (create_kdump_vmcore(s) < 0) {
1711             error_set(errp, QERR_IO_ERROR);
1712         }
1713     } else {
1714         if (create_vmcore(s) < 0) {
1715             error_set(errp, QERR_IO_ERROR);
1716         }
1717     }
1718
1719     g_free(s);
1720 }
1721
1722 DumpGuestMemoryCapability *qmp_query_dump_guest_memory_capability(Error **errp)
1723 {
1724     DumpGuestMemoryFormatList *item;
1725     DumpGuestMemoryCapability *cap =
1726                                   g_malloc0(sizeof(DumpGuestMemoryCapability));
1727
1728     /* elf is always available */
1729     item = g_malloc0(sizeof(DumpGuestMemoryFormatList));
1730     cap->formats = item;
1731     item->value = DUMP_GUEST_MEMORY_FORMAT_ELF;
1732
1733     /* kdump-zlib is always available */
1734     item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
1735     item = item->next;
1736     item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB;
1737
1738     /* add new item if kdump-lzo is available */
1739 #ifdef CONFIG_LZO
1740     item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
1741     item = item->next;
1742     item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO;
1743 #endif
1744
1745     /* add new item if kdump-snappy is available */
1746 #ifdef CONFIG_SNAPPY
1747     item->next = g_malloc0(sizeof(DumpGuestMemoryFormatList));
1748     item = item->next;
1749     item->value = DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY;
1750 #endif
1751
1752     return cap;
1753 }