1*32cad1ffSPhilippe Mathieu-Daudé /* 2*32cad1ffSPhilippe Mathieu-Daudé * QEMU dump 3*32cad1ffSPhilippe Mathieu-Daudé * 4*32cad1ffSPhilippe Mathieu-Daudé * Copyright Fujitsu, Corp. 2011, 2012 5*32cad1ffSPhilippe Mathieu-Daudé * 6*32cad1ffSPhilippe Mathieu-Daudé * Authors: 7*32cad1ffSPhilippe Mathieu-Daudé * Wen Congyang <wency@cn.fujitsu.com> 8*32cad1ffSPhilippe Mathieu-Daudé * 9*32cad1ffSPhilippe Mathieu-Daudé * This work is licensed under the terms of the GNU GPL, version 2 or later. 10*32cad1ffSPhilippe Mathieu-Daudé * See the COPYING file in the top-level directory. 11*32cad1ffSPhilippe Mathieu-Daudé * 12*32cad1ffSPhilippe Mathieu-Daudé */ 13*32cad1ffSPhilippe Mathieu-Daudé 14*32cad1ffSPhilippe Mathieu-Daudé #ifndef DUMP_H 15*32cad1ffSPhilippe Mathieu-Daudé #define DUMP_H 16*32cad1ffSPhilippe Mathieu-Daudé 17*32cad1ffSPhilippe Mathieu-Daudé #include "qapi/qapi-types-dump.h" 18*32cad1ffSPhilippe Mathieu-Daudé #include "qemu/thread.h" 19*32cad1ffSPhilippe Mathieu-Daudé 20*32cad1ffSPhilippe Mathieu-Daudé #define MAKEDUMPFILE_SIGNATURE "makedumpfile" 21*32cad1ffSPhilippe Mathieu-Daudé #define MAX_SIZE_MDF_HEADER (4096) /* max size of makedumpfile_header */ 22*32cad1ffSPhilippe Mathieu-Daudé #define TYPE_FLAT_HEADER (1) /* type of flattened format */ 23*32cad1ffSPhilippe Mathieu-Daudé #define VERSION_FLAT_HEADER (1) /* version of flattened format */ 24*32cad1ffSPhilippe Mathieu-Daudé #define END_FLAG_FLAT_HEADER (-1) 25*32cad1ffSPhilippe Mathieu-Daudé 26*32cad1ffSPhilippe Mathieu-Daudé #ifndef ARCH_PFN_OFFSET 27*32cad1ffSPhilippe Mathieu-Daudé #define ARCH_PFN_OFFSET (0) 28*32cad1ffSPhilippe Mathieu-Daudé #endif 29*32cad1ffSPhilippe Mathieu-Daudé 30*32cad1ffSPhilippe Mathieu-Daudé /* 31*32cad1ffSPhilippe Mathieu-Daudé * flag for compressed format 32*32cad1ffSPhilippe Mathieu-Daudé */ 33*32cad1ffSPhilippe Mathieu-Daudé #define DUMP_DH_COMPRESSED_ZLIB (0x1) 34*32cad1ffSPhilippe Mathieu-Daudé #define DUMP_DH_COMPRESSED_LZO (0x2) 35*32cad1ffSPhilippe Mathieu-Daudé #define DUMP_DH_COMPRESSED_SNAPPY (0x4) 36*32cad1ffSPhilippe Mathieu-Daudé 37*32cad1ffSPhilippe Mathieu-Daudé #define KDUMP_SIGNATURE "KDUMP " 38*32cad1ffSPhilippe Mathieu-Daudé #define SIG_LEN (sizeof(KDUMP_SIGNATURE) - 1) 39*32cad1ffSPhilippe Mathieu-Daudé #define DUMP_LEVEL (1) 40*32cad1ffSPhilippe Mathieu-Daudé #define DISKDUMP_HEADER_BLOCKS (1) 41*32cad1ffSPhilippe Mathieu-Daudé 42*32cad1ffSPhilippe Mathieu-Daudé #include "system/dump-arch.h" 43*32cad1ffSPhilippe Mathieu-Daudé #include "system/memory_mapping.h" 44*32cad1ffSPhilippe Mathieu-Daudé 45*32cad1ffSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED MakedumpfileHeader { 46*32cad1ffSPhilippe Mathieu-Daudé char signature[16]; /* = "makedumpfile" */ 47*32cad1ffSPhilippe Mathieu-Daudé int64_t type; 48*32cad1ffSPhilippe Mathieu-Daudé int64_t version; 49*32cad1ffSPhilippe Mathieu-Daudé } MakedumpfileHeader; 50*32cad1ffSPhilippe Mathieu-Daudé 51*32cad1ffSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED MakedumpfileDataHeader { 52*32cad1ffSPhilippe Mathieu-Daudé int64_t offset; 53*32cad1ffSPhilippe Mathieu-Daudé int64_t buf_size; 54*32cad1ffSPhilippe Mathieu-Daudé } MakedumpfileDataHeader; 55*32cad1ffSPhilippe Mathieu-Daudé 56*32cad1ffSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED NewUtsname { 57*32cad1ffSPhilippe Mathieu-Daudé char sysname[65]; 58*32cad1ffSPhilippe Mathieu-Daudé char nodename[65]; 59*32cad1ffSPhilippe Mathieu-Daudé char release[65]; 60*32cad1ffSPhilippe Mathieu-Daudé char version[65]; 61*32cad1ffSPhilippe Mathieu-Daudé char machine[65]; 62*32cad1ffSPhilippe Mathieu-Daudé char domainname[65]; 63*32cad1ffSPhilippe Mathieu-Daudé } NewUtsname; 64*32cad1ffSPhilippe Mathieu-Daudé 65*32cad1ffSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED DiskDumpHeader32 { 66*32cad1ffSPhilippe Mathieu-Daudé char signature[SIG_LEN]; /* = "KDUMP " */ 67*32cad1ffSPhilippe Mathieu-Daudé uint32_t header_version; /* Dump header version */ 68*32cad1ffSPhilippe Mathieu-Daudé NewUtsname utsname; /* copy of system_utsname */ 69*32cad1ffSPhilippe Mathieu-Daudé char timestamp[10]; /* Time stamp */ 70*32cad1ffSPhilippe Mathieu-Daudé uint32_t status; /* Above flags */ 71*32cad1ffSPhilippe Mathieu-Daudé uint32_t block_size; /* Size of a block in byte */ 72*32cad1ffSPhilippe Mathieu-Daudé uint32_t sub_hdr_size; /* Size of arch dependent header in block */ 73*32cad1ffSPhilippe Mathieu-Daudé uint32_t bitmap_blocks; /* Size of Memory bitmap in block */ 74*32cad1ffSPhilippe Mathieu-Daudé uint32_t max_mapnr; /* = max_mapnr , 75*32cad1ffSPhilippe Mathieu-Daudé obsoleted in header_version 6 */ 76*32cad1ffSPhilippe Mathieu-Daudé uint32_t total_ram_blocks; /* Number of blocks should be written */ 77*32cad1ffSPhilippe Mathieu-Daudé uint32_t device_blocks; /* Number of total blocks in dump device */ 78*32cad1ffSPhilippe Mathieu-Daudé uint32_t written_blocks; /* Number of written blocks */ 79*32cad1ffSPhilippe Mathieu-Daudé uint32_t current_cpu; /* CPU# which handles dump */ 80*32cad1ffSPhilippe Mathieu-Daudé uint32_t nr_cpus; /* Number of CPUs */ 81*32cad1ffSPhilippe Mathieu-Daudé } DiskDumpHeader32; 82*32cad1ffSPhilippe Mathieu-Daudé 83*32cad1ffSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED DiskDumpHeader64 { 84*32cad1ffSPhilippe Mathieu-Daudé char signature[SIG_LEN]; /* = "KDUMP " */ 85*32cad1ffSPhilippe Mathieu-Daudé uint32_t header_version; /* Dump header version */ 86*32cad1ffSPhilippe Mathieu-Daudé NewUtsname utsname; /* copy of system_utsname */ 87*32cad1ffSPhilippe Mathieu-Daudé char timestamp[22]; /* Time stamp */ 88*32cad1ffSPhilippe Mathieu-Daudé uint32_t status; /* Above flags */ 89*32cad1ffSPhilippe Mathieu-Daudé uint32_t block_size; /* Size of a block in byte */ 90*32cad1ffSPhilippe Mathieu-Daudé uint32_t sub_hdr_size; /* Size of arch dependent header in block */ 91*32cad1ffSPhilippe Mathieu-Daudé uint32_t bitmap_blocks; /* Size of Memory bitmap in block */ 92*32cad1ffSPhilippe Mathieu-Daudé uint32_t max_mapnr; /* = max_mapnr, 93*32cad1ffSPhilippe Mathieu-Daudé obsoleted in header_version 6 */ 94*32cad1ffSPhilippe Mathieu-Daudé uint32_t total_ram_blocks; /* Number of blocks should be written */ 95*32cad1ffSPhilippe Mathieu-Daudé uint32_t device_blocks; /* Number of total blocks in dump device */ 96*32cad1ffSPhilippe Mathieu-Daudé uint32_t written_blocks; /* Number of written blocks */ 97*32cad1ffSPhilippe Mathieu-Daudé uint32_t current_cpu; /* CPU# which handles dump */ 98*32cad1ffSPhilippe Mathieu-Daudé uint32_t nr_cpus; /* Number of CPUs */ 99*32cad1ffSPhilippe Mathieu-Daudé } DiskDumpHeader64; 100*32cad1ffSPhilippe Mathieu-Daudé 101*32cad1ffSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED KdumpSubHeader32 { 102*32cad1ffSPhilippe Mathieu-Daudé uint32_t phys_base; 103*32cad1ffSPhilippe Mathieu-Daudé uint32_t dump_level; /* header_version 1 and later */ 104*32cad1ffSPhilippe Mathieu-Daudé uint32_t split; /* header_version 2 and later */ 105*32cad1ffSPhilippe Mathieu-Daudé uint32_t start_pfn; /* header_version 2 and later, 106*32cad1ffSPhilippe Mathieu-Daudé obsoleted in header_version 6 */ 107*32cad1ffSPhilippe Mathieu-Daudé uint32_t end_pfn; /* header_version 2 and later, 108*32cad1ffSPhilippe Mathieu-Daudé obsoleted in header_version 6 */ 109*32cad1ffSPhilippe Mathieu-Daudé uint64_t offset_vmcoreinfo; /* header_version 3 and later */ 110*32cad1ffSPhilippe Mathieu-Daudé uint32_t size_vmcoreinfo; /* header_version 3 and later */ 111*32cad1ffSPhilippe Mathieu-Daudé uint64_t offset_note; /* header_version 4 and later */ 112*32cad1ffSPhilippe Mathieu-Daudé uint32_t note_size; /* header_version 4 and later */ 113*32cad1ffSPhilippe Mathieu-Daudé uint64_t offset_eraseinfo; /* header_version 5 and later */ 114*32cad1ffSPhilippe Mathieu-Daudé uint32_t size_eraseinfo; /* header_version 5 and later */ 115*32cad1ffSPhilippe Mathieu-Daudé uint64_t start_pfn_64; /* header_version 6 and later */ 116*32cad1ffSPhilippe Mathieu-Daudé uint64_t end_pfn_64; /* header_version 6 and later */ 117*32cad1ffSPhilippe Mathieu-Daudé uint64_t max_mapnr_64; /* header_version 6 and later */ 118*32cad1ffSPhilippe Mathieu-Daudé } KdumpSubHeader32; 119*32cad1ffSPhilippe Mathieu-Daudé 120*32cad1ffSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED KdumpSubHeader64 { 121*32cad1ffSPhilippe Mathieu-Daudé uint64_t phys_base; 122*32cad1ffSPhilippe Mathieu-Daudé uint32_t dump_level; /* header_version 1 and later */ 123*32cad1ffSPhilippe Mathieu-Daudé uint32_t split; /* header_version 2 and later */ 124*32cad1ffSPhilippe Mathieu-Daudé uint64_t start_pfn; /* header_version 2 and later, 125*32cad1ffSPhilippe Mathieu-Daudé obsoleted in header_version 6 */ 126*32cad1ffSPhilippe Mathieu-Daudé uint64_t end_pfn; /* header_version 2 and later, 127*32cad1ffSPhilippe Mathieu-Daudé obsoleted in header_version 6 */ 128*32cad1ffSPhilippe Mathieu-Daudé uint64_t offset_vmcoreinfo; /* header_version 3 and later */ 129*32cad1ffSPhilippe Mathieu-Daudé uint64_t size_vmcoreinfo; /* header_version 3 and later */ 130*32cad1ffSPhilippe Mathieu-Daudé uint64_t offset_note; /* header_version 4 and later */ 131*32cad1ffSPhilippe Mathieu-Daudé uint64_t note_size; /* header_version 4 and later */ 132*32cad1ffSPhilippe Mathieu-Daudé uint64_t offset_eraseinfo; /* header_version 5 and later */ 133*32cad1ffSPhilippe Mathieu-Daudé uint64_t size_eraseinfo; /* header_version 5 and later */ 134*32cad1ffSPhilippe Mathieu-Daudé uint64_t start_pfn_64; /* header_version 6 and later */ 135*32cad1ffSPhilippe Mathieu-Daudé uint64_t end_pfn_64; /* header_version 6 and later */ 136*32cad1ffSPhilippe Mathieu-Daudé uint64_t max_mapnr_64; /* header_version 6 and later */ 137*32cad1ffSPhilippe Mathieu-Daudé } KdumpSubHeader64; 138*32cad1ffSPhilippe Mathieu-Daudé 139*32cad1ffSPhilippe Mathieu-Daudé typedef struct DataCache { 140*32cad1ffSPhilippe Mathieu-Daudé DumpState *state; /* dump state related to this data */ 141*32cad1ffSPhilippe Mathieu-Daudé uint8_t *buf; /* buffer for cached data */ 142*32cad1ffSPhilippe Mathieu-Daudé size_t buf_size; /* size of the buf */ 143*32cad1ffSPhilippe Mathieu-Daudé size_t data_size; /* size of cached data in buf */ 144*32cad1ffSPhilippe Mathieu-Daudé off_t offset; /* offset of the file */ 145*32cad1ffSPhilippe Mathieu-Daudé } DataCache; 146*32cad1ffSPhilippe Mathieu-Daudé 147*32cad1ffSPhilippe Mathieu-Daudé typedef struct QEMU_PACKED PageDescriptor { 148*32cad1ffSPhilippe Mathieu-Daudé uint64_t offset; /* the offset of the page data*/ 149*32cad1ffSPhilippe Mathieu-Daudé uint32_t size; /* the size of this dump page */ 150*32cad1ffSPhilippe Mathieu-Daudé uint32_t flags; /* flags */ 151*32cad1ffSPhilippe Mathieu-Daudé uint64_t page_flags; /* page flags */ 152*32cad1ffSPhilippe Mathieu-Daudé } PageDescriptor; 153*32cad1ffSPhilippe Mathieu-Daudé 154*32cad1ffSPhilippe Mathieu-Daudé typedef struct DumpState { 155*32cad1ffSPhilippe Mathieu-Daudé GuestPhysBlockList guest_phys_blocks; 156*32cad1ffSPhilippe Mathieu-Daudé ArchDumpInfo dump_info; 157*32cad1ffSPhilippe Mathieu-Daudé MemoryMappingList list; 158*32cad1ffSPhilippe Mathieu-Daudé bool resume; 159*32cad1ffSPhilippe Mathieu-Daudé bool detached; 160*32cad1ffSPhilippe Mathieu-Daudé bool kdump_raw; 161*32cad1ffSPhilippe Mathieu-Daudé hwaddr memory_offset; 162*32cad1ffSPhilippe Mathieu-Daudé int fd; 163*32cad1ffSPhilippe Mathieu-Daudé 164*32cad1ffSPhilippe Mathieu-Daudé /* 165*32cad1ffSPhilippe Mathieu-Daudé * Dump filter area variables 166*32cad1ffSPhilippe Mathieu-Daudé * 167*32cad1ffSPhilippe Mathieu-Daudé * A filtered dump only contains the guest memory designated by 168*32cad1ffSPhilippe Mathieu-Daudé * the start address and length variables defined below. 169*32cad1ffSPhilippe Mathieu-Daudé * 170*32cad1ffSPhilippe Mathieu-Daudé * If length is 0, no filtering is applied. 171*32cad1ffSPhilippe Mathieu-Daudé */ 172*32cad1ffSPhilippe Mathieu-Daudé int64_t filter_area_begin; /* Start address of partial guest memory area */ 173*32cad1ffSPhilippe Mathieu-Daudé int64_t filter_area_length; /* Length of partial guest memory area */ 174*32cad1ffSPhilippe Mathieu-Daudé 175*32cad1ffSPhilippe Mathieu-Daudé /* Elf dump related data */ 176*32cad1ffSPhilippe Mathieu-Daudé uint32_t phdr_num; 177*32cad1ffSPhilippe Mathieu-Daudé uint32_t shdr_num; 178*32cad1ffSPhilippe Mathieu-Daudé ssize_t note_size; 179*32cad1ffSPhilippe Mathieu-Daudé hwaddr shdr_offset; 180*32cad1ffSPhilippe Mathieu-Daudé hwaddr phdr_offset; 181*32cad1ffSPhilippe Mathieu-Daudé hwaddr section_offset; 182*32cad1ffSPhilippe Mathieu-Daudé hwaddr note_offset; 183*32cad1ffSPhilippe Mathieu-Daudé 184*32cad1ffSPhilippe Mathieu-Daudé void *elf_section_hdrs; /* Pointer to section header buffer */ 185*32cad1ffSPhilippe Mathieu-Daudé void *elf_section_data; /* Pointer to section data buffer */ 186*32cad1ffSPhilippe Mathieu-Daudé uint64_t elf_section_data_size; /* Size of section data */ 187*32cad1ffSPhilippe Mathieu-Daudé GArray *string_table_buf; /* String table data buffer */ 188*32cad1ffSPhilippe Mathieu-Daudé 189*32cad1ffSPhilippe Mathieu-Daudé uint8_t *note_buf; /* buffer for notes */ 190*32cad1ffSPhilippe Mathieu-Daudé size_t note_buf_offset; /* the writing place in note_buf */ 191*32cad1ffSPhilippe Mathieu-Daudé uint32_t nr_cpus; /* number of guest's cpu */ 192*32cad1ffSPhilippe Mathieu-Daudé uint64_t max_mapnr; /* the biggest guest's phys-mem's number */ 193*32cad1ffSPhilippe Mathieu-Daudé size_t len_dump_bitmap; /* the size of the place used to store 194*32cad1ffSPhilippe Mathieu-Daudé dump_bitmap in vmcore */ 195*32cad1ffSPhilippe Mathieu-Daudé off_t offset_dump_bitmap; /* offset of dump_bitmap part in vmcore */ 196*32cad1ffSPhilippe Mathieu-Daudé off_t offset_page; /* offset of page part in vmcore */ 197*32cad1ffSPhilippe Mathieu-Daudé size_t num_dumpable; /* number of page that can be dumped */ 198*32cad1ffSPhilippe Mathieu-Daudé uint32_t flag_compress; /* indicate the compression format */ 199*32cad1ffSPhilippe Mathieu-Daudé DumpStatus status; /* current dump status */ 200*32cad1ffSPhilippe Mathieu-Daudé 201*32cad1ffSPhilippe Mathieu-Daudé bool has_format; /* whether format is provided */ 202*32cad1ffSPhilippe Mathieu-Daudé DumpGuestMemoryFormat format; /* valid only if has_format == true */ 203*32cad1ffSPhilippe Mathieu-Daudé QemuThread dump_thread; /* thread for detached dump */ 204*32cad1ffSPhilippe Mathieu-Daudé 205*32cad1ffSPhilippe Mathieu-Daudé int64_t total_size; /* total memory size (in bytes) to 206*32cad1ffSPhilippe Mathieu-Daudé * be dumped. When filter is 207*32cad1ffSPhilippe Mathieu-Daudé * enabled, this will only count 208*32cad1ffSPhilippe Mathieu-Daudé * those to be written. */ 209*32cad1ffSPhilippe Mathieu-Daudé int64_t written_size; /* written memory size (in bytes), 210*32cad1ffSPhilippe Mathieu-Daudé * this could be used to calculate 211*32cad1ffSPhilippe Mathieu-Daudé * how much work we have 212*32cad1ffSPhilippe Mathieu-Daudé * finished. */ 213*32cad1ffSPhilippe Mathieu-Daudé uint8_t *guest_note; /* ELF note content */ 214*32cad1ffSPhilippe Mathieu-Daudé size_t guest_note_size; 215*32cad1ffSPhilippe Mathieu-Daudé } DumpState; 216*32cad1ffSPhilippe Mathieu-Daudé 217*32cad1ffSPhilippe Mathieu-Daudé uint16_t cpu_to_dump16(DumpState *s, uint16_t val); 218*32cad1ffSPhilippe Mathieu-Daudé uint32_t cpu_to_dump32(DumpState *s, uint32_t val); 219*32cad1ffSPhilippe Mathieu-Daudé uint64_t cpu_to_dump64(DumpState *s, uint64_t val); 220*32cad1ffSPhilippe Mathieu-Daudé 221*32cad1ffSPhilippe Mathieu-Daudé int64_t dump_filtered_memblock_size(GuestPhysBlock *block, int64_t filter_area_start, 222*32cad1ffSPhilippe Mathieu-Daudé int64_t filter_area_length); 223*32cad1ffSPhilippe Mathieu-Daudé int64_t dump_filtered_memblock_start(GuestPhysBlock *block, int64_t filter_area_start, 224*32cad1ffSPhilippe Mathieu-Daudé int64_t filter_area_length); 225*32cad1ffSPhilippe Mathieu-Daudé #endif 226