introducing a new, dedicated guest memory dump mechanism
v11 cover introducing a new, dedicated guest memory dump mechanism
Hi, all
'virsh dump' can not work when host pci device is used by guest. We have discussed this issue here:
http://lists.nongnu.org/archive/html/qemu-devel/2011-10/msg00736.html
The last version is here:
http://lists.nongnu.org/archive/html/qemu-devel/2012-03/msg03866.html
We have determined to introduce a new command dump-guest-memory to dump guest's memory. The core file's format is elf32 or elf64.
Note:
1. The guest should be x86 or x86_64. The other arch is not supported now.
2. If you use old gdb, gdb may crash. I use gdb-7.3.1, and it does not crash.
3. If the OS is in the second kernel, gdb may not work well, and crash can work by specifying '--machdep phys_addr=xxx' in the command line. The reason is that the second kernel will update the page table, and we can not get the page table for the first kernel.
4. The cpu's state is stored in QEMU note. You neet to modify crash to use it to calculate phys_base.
5. If the guest OS is 32 bit and the memory size is larger than 4G, the vmcore is elf64 format. You should use the gdb which is built with --enable-64-bit-bfd.
6. This patchset is based on the upstream tree, and apply one patch that is still in Luiz Capitulino's tree, because I use the API qemu_get_fd() in this patchset.
Changes from v10 to v11:
1. addressed Luiz's and Hatayam's comment
2. fix a bug about filtering feature
Changes from v9 to v10:
1. fix some bug
2. addressed Luiz's and Hatayam's comment
3. remove cancel and query command
Changes from v8 to v9:
1. remove async support(it will be reimplemented after QAPI async commands support is finished)
2. fix some typo error
Changes from v7 to v8:
1. addressed Hatayama's comments
Changes from v6 to v7:
1. addressed Jan's comments
2. fix some bugs
3. store cpu's state into the vmcore
Changes from v5 to v6:
1. allow user to dump a fraction of the memory
2. fix some bugs
Changes from v4 to v5:
1. convert the new command dump to QAPI
Changes from v3 to v4:
1. support it to run asynchronously
2. add API to cancel dumping and query dumping progress
3. add API to control dumping speed
4. auto cancel dumping when the user resumes vm, and the status is failed.
Changes from v2 to v3:
1. address Jan Kiszka's comment
Changes from v1 to v2:
1. fix virt addr in the vmcore.
Wen Congyang (12):
Add API to create memory mapping list
Add API to check whether a physical address is I/O address implement cpu_get_memory_mapping()
Add API to check whether paging mode is enabled
Add API to get memory mapping
Add API to get memory mapping without do paging
target-i386: Add API to write elf notes to core file
target-i386: Add API to write cpu status to core file
target-i386: add API to get dump info
make gdb_id() generally avialable and rename it to cpu_index()
QError: Introduce new error for the dump-guest-memory command introduce a new monitor command 'dump-guest-memory' to dump guest's
memory
Makefile.target | 3 + configure | 8 + cpu-all.h | 67 +++ cpu-common.h | 2 + dump.c | 827 +++++++++++++++++++++++++++++++++++++ dump.h | 23 + elf.h | 5 + exec.c | 9 + gdbstub.c | 19 +- gdbstub.h | 9 + hmp-commands.hx | 28 ++ hmp.c | 22 + hmp.h | 1 + memory_mapping.c | 236 +++++++++++ memory_mapping.h | 68 +++ qapi-schema.json | 34 ++ qerror.c | 4 + qerror.h | 3 + qmp-commands.hx | 38 ++ target-i386/arch_dump.c | 426 +++++++++++++++++++ target-i386/arch_memory_mapping.c | 271 ++++++++++++ 21 files changed, 2089 insertions(+), 14 deletions(-) create mode 100644 dump.c create mode 100644 dump.h create mode 100644 memory_mapping.c create mode 100644 memory_mapping.h create mode 100644 target-i386/arch_dump.c create mode 100644 target-i386/arch_memory_mapping.c
PATCH v11 1/12 Add API to create memory mapping list
The memory mapping list stores virtual address and physical address mapping. The virtual address and physical address are contiguous in the mapping. The folloing patch will use this information to create PT_LOAD in the vmcore.
--- Makefile.target | 1 + memory_mapping.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ memory_mapping.h | 47 +++++++++++++++ 3 files changed, 214 insertions(+), 0 deletions(-) create mode 100644 memory_mapping.c create mode 100644 memory_mapping.h
Makefile.target +1 -0
@@ -220,6 +220,7 @@ obj-$(CONFIG_KVM) += kvm.o kvm-all.o obj-$(CONFIG_NO_KVM) += kvm-stub.o obj-$(CONFIG_VGA) += vga.o obj-y += memory.o savevm.o +obj-y += memory_mapping.o LIBS+=-lz obj-i386-$(CONFIG_KVM) += hyperv.o
memory_mapping.c new file +166 -0
166 lines not on this page · raw message
memory_mapping.h new file +47 -0
47 lines not on this page · raw message
Signature · 1 line
1.7.1
PATCH v12 2/12 Add API to check whether a physical address is I/O address
In reply to Wen CongyangThis API will be used in the following patch.
--- cpu-common.h | 2 ++ exec.c | 9 +++++++++ 2 files changed, 11 insertions(+), 0 deletions(-)
cpu-common.h +2 -0
@@ -71,6 +71,8 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,void *cpu_register_map_client (void *opaque,void (*callback)(void *opaque));void cpu_unregister_map_client (void *cookie); +bool cpu_physical_memory_is_io (target_phys_addr_t phys_addr); +/* Coalesced MMIO regions are areas where write operations can be reordered. * This usually implies that write operations are side-effect free. This allows * batching which can make a major impact on performance when using
exec.c +9 -0
@@ -4657,3 +4657,12 @@ bool virtio_is_big_endian(void)#undef env#endif + +bool cpu_physical_memory_is_io (target_phys_addr_t phys_addr) +{ +MemoryRegionSection *section; + + section =phys_page_find (phys_addr >>TARGET_PAGE_BITS ); + +return !is_ram_rom_romd (section); +}
Signature · 1 line
1.7.1
PATCH v11 3/12 implement cpu_get_memory_mapping()
In reply to Wen CongyangWalk cpu's page table and collect all virtual address and physical address mapping. Then, add these mapping into memory mapping list. If the guest does not use paging, it will do nothing. Note: the I/O memory will be skipped.
--- Makefile.target | 1 + configure | 4 + cpu-all.h | 11 ++ target-i386/arch_memory_mapping.c | 266 +++++++++++++++++++++++++++++++++++++ 4 files changed, 282 insertions(+), 0 deletions(-) create mode 100644 target-i386/arch_memory_mapping.c
Makefile.target +1 -0
@@ -89,6 +89,7 @@ libobj-y += helper.o ifeq ($(TARGET_BASE_ARCH), i386) libobj-y += cpuid.o endif +libobj-$(CONFIG_HAVE_GET_MEMORY_MAPPING) += arch_memory_mapping.o libobj-$(TARGET_SPARC64) += vis_helper.o libobj-$(CONFIG_NEED_MMU) += mmu.o libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o
configure +4 -0
@@ -3659,6 +3659,10 @@ case "$target_arch2" in fi fi esac +case "$target_arch2" in + i386|x86_64) + echo "CONFIG_HAVE_GET_MEMORY_MAPPING=y" >> $config_target_mak +esac if test "$target_arch2" = "ppc64" -a "$fdt" = "yes"; then echo "CONFIG_PSERIES=y" >> $config_target_mak fi
cpu-all.h +11 -0
@@ -22,6 +22,7 @@#include "qemu-common.h" #include "qemu-tls.h" #include "cpu-common.h" +#include "memory_mapping.h" /* some important defines: *
@@ -525,4 +526,14 @@ void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);int cpu_memory_rw_debug (CPUArchState *env,target_ulong addr,uint8_t *buf,int len,int is_write); +#if defined(CONFIG_HAVE_GET_MEMORY_MAPPING ) +int cpu_get_memory_mapping (MemoryMappingList *list,CPUArchState *env); +#else +static inline int cpu_get_memory_mapping (MemoryMappingList *list, +CPUArchState *env) +{ +return -1 ; +} +#endif +#endif /* CPU_ALL_H */
target-i386/arch_memory_mapping.c new file +266 -0
266 lines not on this page · raw message
Signature · 1 line
1.7.1
PATCH v11 4/12 Add API to check whether paging mode is enabled
In reply to Wen CongyangThis API will be used in the following patch.
--- cpu-all.h | 6 ++++++ target-i386/arch_memory_mapping.c | 7 ++++++- 2 files changed, 12 insertions(+), 1 deletions(-)
cpu-all.h +6 -0
@@ -528,12 +528,18 @@ int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,#if defined(CONFIG_HAVE_GET_MEMORY_MAPPING )int cpu_get_memory_mapping (MemoryMappingList *list,CPUArchState *env); +bool cpu_paging_enabled (CPUArchState *env);#else static inline int cpu_get_memory_mapping (MemoryMappingList *list,CPUArchState *env) {return -1 ; } + +static inline bool cpu_paging_enabled (CPUArchState *env) +{ +return true; +}#endif #endif /* CPU_ALL_H */
target-i386/arch_memory_mapping.c +6 -1
@@ -233,7 +233,7 @@ static void walk_pml4e(MemoryMappingList *list,int cpu_get_memory_mapping (MemoryMappingList *list,CPUArchState *env) { -if (!(env->cr[0 ] &CR0_PG_MASK )) { +if (!cpu_paging_enabled (env)) {/* paging is disabled */ return 0 ; }
@@ -264,3 +264,8 @@ int cpu_get_memory_mapping(MemoryMappingList *list, CPUArchState *env)return 0 ; } + +bool cpu_paging_enabled (CPUArchState *env) +{ +return env->cr[0 ] &CR0_PG_MASK ; +}
Signature · 1 line
1.7.1
PATCH v11 5/12 Add API to get memory mapping
In reply to Wen CongyangAdd API to get all virtual address and physical address mapping.
If the guest doesn't use paging, the virtual address is equal to the phyical address. The virtual address and physical address mapping is for gdb's user, and it does not include the memory that is not referenced by the page table. So if you want to use crash to anaylze the vmcore, please do not specify -p option. the reason why the -p option is not default explicitly: guest machine in a catastrophic state can have corrupted memory, which we cannot trust.
--- memory_mapping.c | 34 ++++++++++++++++++++++++++++++++++ memory_mapping.h | 15 +++++++++++++++ 2 files changed, 49 insertions(+), 0 deletions(-)
memory_mapping.c +34 -0
@@ -164,3 +164,37 @@ void memory_mapping_list_init(MemoryMappingList *list) list->last_mapping =NULL ;QTAILQ_INIT (&list->head); } + +#if defined(CONFIG_HAVE_GET_MEMORY_MAPPING ) +int qemu_get_guest_memory_mapping (MemoryMappingList *list) +{ +CPUArchState *env; +RAMBlock *block; +ram_addr_t offset, length; +int ret; +bool paging_mode; + + paging_mode =cpu_paging_enabled (first_cpu); +if (paging_mode) { +for (env = first_cpu; env !=NULL ; env = env->next_cpu) { + ret =cpu_get_memory_mapping (list, env); +if (ret <0 ) { +return -1 ; + } + } +return 0 ; + } + +/* +* If the guest doesn't use paging, the virtual address is equal to physical +* address. +*/ + QLIST_FOREACH(block, &ram_list.blocks, next) { + offset = block->offset; + length = block->length; +create_new_memory_mapping (list, offset, offset, length); + } + +return 0 ; +} +#endif
memory_mapping.h +15 -0
@@ -44,4 +44,19 @@ void memory_mapping_list_free(MemoryMappingList *list);void memory_mapping_list_init (MemoryMappingList *list); +/* +* Return value: +* 0: success +* -1: failed +* -2: unsupported +*/ +#if defined(CONFIG_HAVE_GET_MEMORY_MAPPING ) +int qemu_get_guest_memory_mapping (MemoryMappingList *list); +#else +static inline int qemu_get_guest_memory_mapping (MemoryMappingList *list) +{ +return -2 ; +} +#endif +#endif
Signature · 1 line
1.7.1
PATCH v11 5/12 Add API to get memory mapping
Add API to get all virtual address and physical address mapping.
If the guest doesn't use paging, the virtual address is equal to the phyical address. The virtual address and physical address mapping is for gdb's user, and it does not include the memory that is not referenced by the page table. So if you want to use crash to anaylze the vmcore, please do not specify -p option. the reason why the -p option is not default explicitly: guest machine in a catastrophic state can have corrupted memory, which we cannot trust.
---
address hatayama's comment
memory_mapping.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ memory_mapping.h | 15 +++++++++++++++ 2 files changed, 62 insertions(+), 0 deletions(-)
memory_mapping.c +47 -0
@@ -164,3 +164,50 @@ void memory_mapping_list_init(MemoryMappingList *list) list->last_mapping =NULL ;QTAILQ_INIT (&list->head); } + +#if defined(CONFIG_HAVE_GET_MEMORY_MAPPING ) + +static CPUArchState *find_paging_enabled_cpu (CPUArchState *start_cpu) +{ +CPUArchState *env; + +for (env = start_cpu; env !=NULL ; env = env->next_cpu) { +if (cpu_paging_enabled (env)) { +return env; + } + } + +return NULL ; +} + +int qemu_get_guest_memory_mapping (MemoryMappingList *list) +{ +CPUArchState *env, *first_paging_enabled_cpu; +RAMBlock *block; +ram_addr_t offset, length; +int ret; + + first_paging_enabled_cpu =find_paging_enabled_cpu (first_cpu); +if (first_paging_enabled_cpu) { +for (env = first_paging_enabled_cpu; env !=NULL ; env = env->next_cpu) { + ret =cpu_get_memory_mapping (list, env); +if (ret <0 ) { +return -1 ; + } + } +return 0 ; + } + +/* +* If the guest doesn't use paging, the virtual address is equal to physical +* address. +*/ + QLIST_FOREACH(block, &ram_list.blocks, next) { + offset = block->offset; + length = block->length; +create_new_memory_mapping (list, offset, offset, length); + } + +return 0 ; +} +#endif
memory_mapping.h +15 -0
@@ -44,4 +44,19 @@ void memory_mapping_list_free(MemoryMappingList *list);void memory_mapping_list_init (MemoryMappingList *list); +/* +* Return value: +* 0: success +* -1: failed +* -2: unsupported +*/ +#if defined(CONFIG_HAVE_GET_MEMORY_MAPPING ) +int qemu_get_guest_memory_mapping (MemoryMappingList *list); +#else +static inline int qemu_get_guest_memory_mapping (MemoryMappingList *list) +{ +return -2 ; +} +#endif +#endif
Signature · 1 line
1.7.1
PATCH v11 6/12 Add API to get memory mapping without do paging
In reply to Wen Congyangcrash does not need the virtual address and physical address mapping, and the mapping does not include the memory that is not referenced by the page table. crash does not use the virtual address, so we can create the mapping for all physical memory(virtual address is always 0). This patch provides a API to do this thing, and it will be used in the following patch.
--- memory_mapping.c | 9 +++++++++ memory_mapping.h | 3 +++ 2 files changed, 12 insertions(+), 0 deletions(-)
memory_mapping.c +9 -0
@@ -198,3 +198,12 @@ int qemu_get_guest_memory_mapping(MemoryMappingList *list)return 0 ; }#endif + +void qemu_get_guest_simple_memory_mapping (MemoryMappingList *list) +{ +RAMBlock *block; + + QLIST_FOREACH(block, &ram_list.blocks, next) { +create_new_memory_mapping (list, block->offset,0 , block->length); + } +}
memory_mapping.h +3 -0
@@ -59,4 +59,7 @@ static inline int qemu_get_guest_memory_mapping(MemoryMappingList *list) }#endif +/* get guest's memory mapping without do paging(virtual address is 0). */ +void qemu_get_guest_simple_memory_mapping (MemoryMappingList *list); +#endif
Signature · 1 line
1.7.1
PATCH v11 7/12 target-i386: Add API to write elf notes to core file
In reply to Wen CongyangThe core file contains register's value. These APIs write registers to core file, and them will be called in the following patch.
--- Makefile.target | 1 + configure | 4 + cpu-all.h | 23 +++++ target-i386/arch_dump.c | 240 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 268 insertions(+), 0 deletions(-) create mode 100644 target-i386/arch_dump.c
Makefile.target +1 -0
@@ -222,6 +222,7 @@ obj-$(CONFIG_NO_KVM) += kvm-stub.o obj-$(CONFIG_VGA) += vga.o obj-y += memory.o savevm.o obj-y += memory_mapping.o +obj-$(CONFIG_HAVE_CORE_DUMP) += arch_dump.o LIBS+=-lz obj-i386-$(CONFIG_KVM) += hyperv.o
configure +4 -0
@@ -3678,6 +3678,10 @@ if test "$target_softmmu" = "yes" ; then if test "$smartcard_nss" = "yes" ; then echo "subdir-$target: subdir-libcacard" >> $config_host_mak fi + case "$target_arch2" in + i386|x86_64) + echo "CONFIG_HAVE_CORE_DUMP=y" >> $config_target_mak + esac fi if test "$target_user_only" = "yes" ; then echo "CONFIG_USER_ONLY=y" >> $config_target_mak
cpu-all.h +23 -0
@@ -542,4 +542,27 @@ static inline bool cpu_paging_enabled(CPUArchState *env) }#endif +typedef int (*write_core_dump_function ) + (target_phys_addr_t offset,void *buf,size_t size,void *opaque); +#if defined(CONFIG_HAVE_CORE_DUMP ) +int cpu_write_elf64_note (write_core_dump_function f,CPUArchState *env, +int cpuid,target_phys_addr_t *offset,void *opaque); +int cpu_write_elf32_note (write_core_dump_function f,CPUArchState *env, +int cpuid,target_phys_addr_t *offset,void *opaque); +#else +static inline int cpu_write_elf64_note (write_core_dump_function f, +CPUArchState *env,int cpuid, +target_phys_addr_t *offset,void *opaque) +{ +return -1 ; +} + +static inline int cpu_write_elf32_note (write_core_dump_function f, +CPUArchState *env,int cpuid, +target_phys_addr_t *offset,void *opaque) +{ +return -1 ; +} +#endif +#endif /* CPU_ALL_H */
target-i386/arch_dump.c new file +240 -0
240 lines not on this page · raw message
Signature · 1 line
1.7.1
PATCH v11 8/12 target-i386: Add API to write cpu status to core file
In reply to Wen CongyangThe core file has register's value. But it does not include all registers value. Store the cpu status into QEMU note, and the user can get more information from vmcore. If you change QEMUCPUState, please count up QEMUCPUSTATE_VERSION.
--- cpu-all.h | 20 ++++++ target-i386/arch_dump.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+), 0 deletions(-)
cpu-all.h +20 -0
@@ -549,6 +549,10 @@ int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env, int cpuid, target_phys_addr_t *offset, void *opaque);int cpu_write_elf32_note (write_core_dump_function f,CPUArchState *env,int cpuid,target_phys_addr_t *offset,void *opaque); +int cpu_write_elf64_qemunote (write_core_dump_function f,CPUArchState *env, +target_phys_addr_t *offset,void *opaque); +int cpu_write_elf32_qemunote (write_core_dump_function f,CPUArchState *env, +target_phys_addr_t *offset,void *opaque);#else static inline int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env, int cpuid,
@@ -563,6 +567,22 @@ static inline int cpu_write_elf32_note(write_core_dump_function f, {return -1 ; } + +static inline int cpu_write_elf64_qemunote (write_core_dump_function f, +CPUArchState *env, +target_phys_addr_t *offset, +void *opaque); +{ +return -1 ; +} + +static inline int cpu_write_elf32_qemunote (write_core_dump_function f, +CPUArchState *env, +target_phys_addr_t *offset, +void *opaque) +{ +return -1 ; +}#endif #endif /* CPU_ALL_H */
target-i386/arch_dump.c +152 -0
155 lines not on this page · raw message
Signature · 1 line
1.7.1
PATCH v11 9/12 target-i386: add API to get dump info
In reply to Wen CongyangDump info contains: endian, class and architecture. The next patch will use these information to create vmcore. Note: on x86 box, the class is ELFCLASS64 if the memory is larger than 4G.
--- cpu-all.h | 7 +++++++ dump.h | 23 +++++++++++++++++++++++ target-i386/arch_dump.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 0 deletions(-) create mode 100644 dump.h
cpu-all.h +7 -0
@@ -23,6 +23,7 @@#include "qemu-tls.h" #include "cpu-common.h" #include "memory_mapping.h" +#include "dump.h" /* some important defines: *
@@ -553,6 +554,7 @@ int cpu_write_elf64_qemunote(write_core_dump_function f, CPUArchState *env, target_phys_addr_t *offset, void *opaque);int cpu_write_elf32_qemunote (write_core_dump_function f,CPUArchState *env,target_phys_addr_t *offset,void *opaque); +int cpu_get_dump_info (ArchDumpInfo *info);#else static inline int cpu_write_elf64_note(write_core_dump_function f, CPUArchState *env, int cpuid,
@@ -583,6 +585,11 @@ static inline int cpu_write_elf32_qemunote(write_core_dump_function f, {return -1 ; } + +static inline int cpu_get_dump_info (ArchDumpInfo *info) +{ +return -1 ; +}#endif #endif /* CPU_ALL_H */
dump.h new file +23 -0
@@ -0,0 +1,23 @@ +/* +* QEMU dump +* +* Copyright Fujitsu, Corp. 2011, 2012 +* +* Authors: +* Wen Congyang <[email protected]> +* +* This work is licensed under the terms of the GNU GPL, version 2. See +* the COPYING file in the top-level directory. +* +*/ + +#ifndef DUMP_H +#define DUMP_H + +typedef struct ArchDumpInfo { +int d_machine;/* Architecture */ +int d_endian;/* ELFDATA2LSB or ELFDATA2MSB */ +int d_class;/* ELFCLASS32 or ELFCLASS64 */ +}ArchDumpInfo ; + +#endif
target-i386/arch_dump.c +34 -0
@@ -13,6 +13,7 @@#include "cpu.h" #include "cpu-all.h" +#include "dump.h" #include "elf.h" #ifdef TARGET_X86_64
@@ -390,3 +391,36 @@ int cpu_write_elf32_qemunote(write_core_dump_function f, CPUArchState *env, {return cpu_write_qemu_note (f, env, offset, opaque,0 ); } + +int cpu_get_dump_info (ArchDumpInfo *info) +{ +bool lma = false; +RAMBlock *block; + +#ifdef TARGET_X86_64 + lma = !!(first_cpu->hflags &HF_LMA_MASK ); +#endif + +if (lma) { + info->d_machine =EM_X86_64 ; + }else { + info->d_machine =EM_386 ; + } + info->d_endian =ELFDATA2LSB ; + +if (lma) { + info->d_class =ELFCLASS64 ; + }else { + info->d_class =ELFCLASS32 ; + + QLIST_FOREACH(block, &ram_list.blocks, next) { +if (block->offset + block->length >UINT_MAX ) { +/* The memory size is greater than 4G */ + info->d_class =ELFCLASS64 ; +break ; + } + } + } + +return 0 ; +}
Signature · 1 line
1.7.1
PATCH v11 10/12 make gdb_id() generally avialable and rename it to cpu_index()
In reply to Wen CongyangThe following patch also needs this API, so make it generally avialable. The function gdb_id() will not be used in gdbstub.c now, so its name is not suitable, and rename it to cpu_index()
--- gdbstub.c | 19 +++++-------------- gdbstub.h | 9 +++++++++ 2 files changed, 14 insertions(+), 14 deletions(-)
gdbstub.c +5 -14
@@ -1938,21 +1938,12 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)#endif } -static inline int gdb_id (CPUArchState *env) -{ -#if defined(CONFIG_USER_ONLY ) && defined(CONFIG_USE_NPTL ) -return env->host_tid; -#else -return env->cpu_index +1 ; -#endif -} -static CPUArchState *find_cpu (uint32_t thread_id) {CPUArchState *env;for (env = first_cpu; env !=NULL ; env = env->next_cpu) { -if (gdb_id (env) == thread_id) { +if (cpu_index (env) == thread_id) {return env; } }
@@ -1980,7 +1971,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)case '?' :/* TODO: Make this return the correct value for user-mode. */ snprintf (buf,sizeof (buf),"T%02xthread:%02x;" ,GDB_SIGNAL_TRAP , -gdb_id (s->c_cpu)); +cpu_index (s->c_cpu));put_packet (s, buf);/* Remove all the breakpoints when this query is issued, * because gdb is doing and initial connect and the state
@@ -2275,7 +2266,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) }else if (strcmp (p,"sThreadInfo" ) ==0 ) { report_cpuinfo:if (s->query_cpu) { -snprintf (buf,sizeof (buf),"m%x" ,gdb_id (s->query_cpu)); +snprintf (buf,sizeof (buf),"m%x" ,cpu_index (s->query_cpu));put_packet (s, buf); s->query_cpu = s->query_cpu->next_cpu; }else
@@ -2423,7 +2414,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state) }snprintf (buf,sizeof (buf),"T%02xthread:%02x;%swatch:" TARGET_FMT_lx";" , -GDB_SIGNAL_TRAP ,gdb_id (env), type, +GDB_SIGNAL_TRAP ,cpu_index (env), type, env->watchpoint_hit->vaddr); env->watchpoint_hit =NULL ; goto send_packet;
@@ -2456,7 +2447,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state) ret =GDB_SIGNAL_UNKNOWN ;break ; } -snprintf (buf,sizeof (buf),"T%02xthread:%02x;" , ret,gdb_id (env)); +snprintf (buf,sizeof (buf),"T%02xthread:%02x;" , ret,cpu_index (env)); send_packet:put_packet (s, buf);
gdbstub.h +9 -0
@@ -30,6 +30,15 @@ void gdb_register_coprocessor(CPUArchState *env, gdb_reg_cb get_reg, gdb_reg_cb set_reg, int num_regs, const char *xml, int g_pos); +static inline int cpu_index (CPUArchState *env) +{ +#if defined(CONFIG_USER_ONLY ) && defined(CONFIG_USE_NPTL ) +return env->host_tid; +#else +return env->cpu_index +1 ; +#endif +} +#endif #ifdef CONFIG_USER_ONLY
Signature · 1 line
1.7.1
Re: [Qemu-devel] [PATCH 10/12 v11] make gdb_id() generally avialable and rename it to cpu_index()
From: Wen Congyang <[email protected]>
Subject: [PATCH 10/12 v11] make gdb_id() generally avialable and rename it to cpu_index()
Date: Mon, 26 Mar 2012 18:05:39 +0800
<cut>
gdbstub.c static void gdb_set_cpu_pc(GDBState *s, target_ulong pc) · line 1949
Quoted 10 lines
gdbstub.c +0
-9-static inline int gdb_id (CPUArchState *env) -{ -#if defined(CONFIG_USER_ONLY ) && defined(CONFIG_USE_NPTL ) -return env->host_tid; -#else -return env->cpu_index +1 ; -#endif -} -
<cut>
I meant in gdbstub.c:
static inline int gdb_id(CPUArchState *env)
{
return cpu_index(env);
}Thanks.
HATAYAMA, Daisuke
PATCH v11 11/12 QError: Introduce new error for the dump-guest-memory command
In reply to Wen CongyangThe new error is QERR_PIPE_OR_SOCKET_FD, which is going to be used by the QAPI dump-guest-memory command.
--- qerror.c | 4 ++++ qerror.h | 3 +++ 2 files changed, 7 insertions(+), 0 deletions(-)
qerror.c +4 -0
@@ -299,6 +299,10 @@ static const QErrorStringTable qerror_table[] = { .error_fmt = QERR_VNC_SERVER_FAILED, .desc = "Could not start VNC server on %(target)", }, + { + .error_fmt = QERR_PIPE_OR_SOCKET_FD, + .desc = "lseek() failed: the fd is associated with a pipe, socket", + }, {} };
qerror.h +3 -0
@@ -244,4 +244,7 @@ QError *qobject_to_qerror(const QObject *obj);#define QERR_VNC_SERVER_FAILED \ "{ 'class': 'VNCServerFailed', 'data': { 'target': %s } }" +#define QERR_PIPE_OR_SOCKET_FD \ + "{ 'class': 'PipeOrSocketFD', 'data': {} }" +#endif /* QERROR_H */
Signature · 1 line
1.7.1
PATCH v11 12/12 introduce a new monitor command 'dump-guest-memory' to dump guest's memory
In reply to Wen CongyangThe command's usage:
dump [-p] protocol [begin] [length]
The supported protocol can be file or fd:
1. file: the protocol starts with "file:", and the following string is the file's path.
2. fd: the protocol starts with "fd:", and the following string is the fd's name.
Note:
1. If you want to use gdb to process the core, please specify -p option. The reason why the -p option is not default is:
a. guest machine in a catastrophic state can have corrupted memory,
which we cannot trust.
b. The guest machine can be in read-mode even if paging is enabled.
For example: the guest machine uses ACPI to sleep, and ACPI sleep state goes in real-mode.
2. This command doesn't support the fd that is is associated with a pipe, socket, or FIFO(lseek will fail with such fd).
3. If you don't want to dump all guest's memory, please specify the start physical address and the length.
--- Makefile.target | 2 +- dump.c | 827 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ elf.h | 5 + hmp-commands.hx | 28 ++ hmp.c | 22 ++ hmp.h | 1 + memory_mapping.c | 27 ++ memory_mapping.h | 3 + qapi-schema.json | 34 +++ qmp-commands.hx | 38 +++ 10 files changed, 986 insertions(+), 1 deletions(-) create mode 100644 dump.c
Makefile.target +1 -1
@@ -222,7 +222,7 @@ obj-$(CONFIG_NO_KVM) += kvm-stub.o obj-$(CONFIG_VGA) += vga.o obj-y += memory.o savevm.o obj-y += memory_mapping.o -obj-$(CONFIG_HAVE_CORE_DUMP) += arch_dump.o +obj-$(CONFIG_HAVE_CORE_DUMP) += arch_dump.o dump.o LIBS+=-lz obj-i386-$(CONFIG_KVM) += hyperv.o
dump.c new file +827 -0
827 lines not on this page · raw message
elf.h +5 -0
@@ -1016,6 +1016,11 @@ typedef struct elf64_sym {#define EI_NIDENT 16 +/* Special value for e_phnum. This indicates that the real number of +program headers is too large to fit into e_phnum. Instead the real +value is in the field sh_info of section 0. */ +#define PN_XNUM 0xffff + typedef struct elf32_hdr{ unsigned char e_ident[EI_NIDENT]; Elf32_Half e_type;
hmp-commands.hx +28 -0
@@ -879,6 +879,34 @@ server will ask the spice/vnc client to automatically reconnect using the new parameters (if specified) once the vm migration finished successfully. ETEXI +#if defined(CONFIG_HAVE_CORE_DUMP) + { + .name = "dump-guest-memory", + .args_type = "paging:-p,protocol:s,begin:i?,length:i?", + .params = "[-p] protocol [begin] [length]", + .help = "dump guest memory to file" + "\n\t\t\t begin(optional): the starting physical address" + "\n\t\t\t length(optional): the memory size, in bytes", + .user_print = monitor_user_noop, + .mhandler.cmd = hmp_dump_guest_memory, + }, + + +STEXI +@item dump-guest-memory [-p] @var{protocol} @var{begin} @var{length} +@findex dump-guest-memory +Dump guest memory to @var{protocol}. The file can be processed with crash or +gdb. + protocol: destination file(started with "file:") or destination file + descriptor (started with "fd:") + paging: do paging to get guest's memory mapping + begin: the starting physical address. It's optional, and should be + specified with length together. + length: the memory size, in bytes. It's optional, and should be specified + with begin together. +ETEXI +#endif + { .name = "snapshot_blkdev", .args_type = "reuse:-n,device:B,snapshot-file:s?,format:s?",
hmp.c +22 -0
@@ -934,3 +934,25 @@ void hmp_migrate(Monitor *mon, const QDict *qdict)qemu_mod_timer (status->timer,qemu_get_clock_ms (rt_clock)); } } + +void hmp_dump_guest_memory (Monitor *mon,const QDict *qdict) +{ +Error *errp =NULL ; +int paging =qdict_get_try_bool (qdict,"paging" ,0 ); +const char *file =qdict_get_str (qdict,"protocol" ); +bool has_begin =qdict_haskey (qdict,"begin" ); +bool has_length =qdict_haskey (qdict,"length" ); +int64_t begin =0 ; +int64_t length =0 ; + +if (has_begin) { + begin =qdict_get_int (qdict,"begin" ); + } +if (has_length) { + length =qdict_get_int (qdict,"length" ); + } + +qmp_dump_guest_memory (paging, file, has_begin, begin, has_length, length, + &errp); +hmp_handle_error (mon, &errp); +}
hmp.h +1 -0
@@ -60,5 +60,6 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict);void hmp_block_job_set_speed (Monitor *mon,const QDict *qdict);void hmp_block_job_cancel (Monitor *mon,const QDict *qdict);void hmp_migrate (Monitor *mon,const QDict *qdict); +void hmp_dump_guest_memory (Monitor *mon,const QDict *qdict);#endif
memory_mapping.c +27 -0
@@ -207,3 +207,30 @@ void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list)create_new_memory_mapping (list, block->offset,0 , block->length); } } + +void memory_mapping_filter (MemoryMappingList *list,int64_t begin, +int64_t length) +{ +MemoryMapping *cur, *next; + + QTAILQ_FOREACH_SAFE(cur, &list->head, next, next) { +if (cur->phys_addr >= begin + length || + cur->phys_addr + cur->length <= begin) { +QTAILQ_REMOVE (&list->head, cur, next); + list->num--; +continue ; + } + +if (cur->phys_addr < begin) { + cur->length -= begin - cur->phys_addr; +if (cur->virt_addr) { + cur->virt_addr += begin - cur->phys_addr; + } + cur->phys_addr = begin; + } + +if (cur->phys_addr + cur->length > begin + length) { + cur->length -= cur->phys_addr + cur->length - begin - length; + } + } +}
memory_mapping.h +3 -0
@@ -62,4 +62,7 @@ static inline int qemu_get_guest_memory_mapping(MemoryMappingList *list)/* get guest's memory mapping without do paging(virtual address is 0). */ void qemu_get_guest_simple_memory_mapping (MemoryMappingList *list); +void memory_mapping_filter (MemoryMappingList *list,int64_t begin, +int64_t length); +#endif
qapi-schema.json +34 -0
@@ -1701,3 +1701,37 @@ # Since: 1.1 ## { 'command': 'xen-save-devices-state', 'data': {'filename': 'str'} } + +## +# @dump-guest-memory +# +# Dump guest's memory to vmcore. +# +# @paging: if true, do paging to get guest's memory mapping. The @paging's +# default value of @paging is false, If you want to use gdb to process the +# core, please set @paging to true. The reason why the @paging's value is +# false: +# 1. guest machine in a catastrophic state can have corrupted memory, +# which we cannot trust. +# 2. The guest machine can be in read-mode even if paging is enabled. +# For example: the guest machine uses ACPI to sleep, and ACPI sleep +# state goes in real-mode +# @protocol: the filename or file descriptor of the vmcore. The supported +# protocol can be file or fd: +# 1. file: the protocol starts with "file:", and the following string is +# the file's path. +# 2. fd: the protocol starts with "fd:", and the following string is the +# fd's name. This command doesn't support the fd that is is associated +# with a pipe, socket, or FIFO(lseek will fail with such fd). +# @begin: #optional if specified, the starting physical address. +# @length: #optional if specified, the memory size, in bytes. If you don't +# want to dump all guest's memory, please specify the start @begin and +# @length +# +# Returns: nothing on success +# +# Since: 1.1 +## +{ 'command': 'dump-guest-memory', + 'data': { 'paging': 'bool', 'protocol': 'str', '*begin': 'int', + '*length': 'int' } }
qmp-commands.hx +38 -0
@@ -606,6 +606,44 @@ Example: EQMP +#if defined(CONFIG_HAVE_CORE_DUMP) + { + .name = "dump-guest-memory", + .args_type = "paging:b,protocol:s,begin:i?,end:i?", + .params = "[-p] protocol [begin] [length]", + .help = "dump guest memory to file", + .user_print = monitor_user_noop, + .mhandler.cmd_new = qmp_marshal_input_dump_guest_memory, + }, + +SQMP +dump + + +Dump guest memory to file. The file can be processed with crash or gdb. + +Arguments: + +- "paging": do paging to get guest's memory mapping (json-bool) +- "protocol": destination file(started with "file:") or destination file + descriptor (started with "fd:") (json-string) +- "begin": the starting physical address. It's optional, and should be specified + with length together (json-int) +- "length": the memory size, in bytes. It's optional, and should be specified + with begin together (json-int) + +Example: + +-> { "execute": "dump-guest-memory", "arguments": { "protocol": "fd:dump" } } +<- { "return": {} } + +Notes: + +(1) All boolean arguments default to false + +EQMP +#endif + { .name = "netdev_add", .args_type = "netdev:O",
Signature · 1 line
1.7.1
Re: [Qemu-devel] [PATCH 12/12 v11] introduce a new monitor command 'dump-guest-memory' to dump guest's memory
At 03/26/2012 06:06 PM, Wen Congyang Wrote:
Quoted 35 lines
The command's usage:
dump [-p] protocol [begin] [length]
The supported protocol can be file or fd:
1. file: the protocol starts with "file:", and the following string is the file's path.
2. fd: the protocol starts with "fd:", and the following string is the fd's name.Note:
1. If you want to use gdb to process the core, please specify -p option. The reason why the -p option is not default is:
a. guest machine in a catastrophic state can have corrupted memory,
which we cannot trust.
b. The guest machine can be in read-mode even if paging is enabled.
For example: the guest machine uses ACPI to sleep, and ACPI sleep state goes in real-mode.
2. This command doesn't support the fd that is is associated with a pipe, socket, or FIFO(lseek will fail with such fd).
3. If you don't want to dump all guest's memory, please specify the start physical address and the length.Signed-off-by Wen Congyang <[email protected]>--- Makefile.target | 2 +- dump.c | 827 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ elf.h | 5 + hmp-commands.hx | 28 ++ hmp.c | 22 ++ hmp.h | 1 + memory_mapping.c | 27 ++ memory_mapping.h | 3 + qapi-schema.json | 34 +++ qmp-commands.hx | 38 +++ 10 files changed, 986 insertions(+), 1 deletions(-) create mode 100644 dump.c
<cut>
dump.c line 421
Quoted 5 lines
dump.c new file +5
-0+/* write the memroy to vmcore. 1 page per I/O. */ +static int write_memory (DumpState *s,RAMBlock *block,ram_addr_t start, +target_phys_addr_t *offset,int64_t size) +{ +int i, ret;
The type of i should be int64_t. Otherwise, i * TARGET_PAGE_SIZE may be overflow.
I will resend this patch.
Thanks
Wen Congyang
Quoted 20 lines
dump.c new file +20
-0+ +for (i =0 ; i < size /TARGET_PAGE_SIZE ; i++) { + ret =write_data (s, block->host + start + i *TARGET_PAGE_SIZE , +TARGET_PAGE_SIZE , offset); +if (ret <0 ) { +return ret; + } + } + +if ((size %TARGET_PAGE_SIZE ) !=0 ) { + ret =write_data (s, block->host + start + i *TARGET_PAGE_SIZE , + size %TARGET_PAGE_SIZE , offset); +if (ret <0 ) { +return ret; + } + } + +return 0 ; +} +
PATCH v11 12/12 introduce a new monitor command 'dump-guest-memory' to dump guest's memory
In reply to Wen CongyangThe command's usage:
dump [-p] protocol [begin] [length]
The supported protocol can be file or fd:
1. file: the protocol starts with "file:", and the following string is the file's path.
2. fd: the protocol starts with "fd:", and the following string is the fd's name.
Note:
1. If you want to use gdb to process the core, please specify -p option. The reason why the -p option is not default is:
a. guest machine in a catastrophic state can have corrupted memory,
which we cannot trust.
b. The guest machine can be in read-mode even if paging is enabled.
For example: the guest machine uses ACPI to sleep, and ACPI sleep state goes in real-mode.
2. This command doesn't support the fd that is is associated with a pipe, socket, or FIFO(lseek will fail with such fd).
3. If you don't want to dump all guest's memory, please specify the start physical address and the length.
--- Makefile.target | 2 +- dump.c | 828 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ elf.h | 5 + hmp-commands.hx | 28 ++ hmp.c | 22 ++ hmp.h | 1 + memory_mapping.c | 27 ++ memory_mapping.h | 3 + qapi-schema.json | 34 +++ qmp-commands.hx | 38 +++ 10 files changed, 987 insertions(+), 1 deletions(-) create mode 100644 dump.c
Makefile.target +1 -1
@@ -224,7 +224,7 @@ obj-$(CONFIG_NO_KVM) += kvm-stub.o obj-$(CONFIG_VGA) += vga.o obj-y += memory.o savevm.o obj-y += memory_mapping.o -obj-$(CONFIG_HAVE_CORE_DUMP) += arch_dump.o +obj-$(CONFIG_HAVE_CORE_DUMP) += arch_dump.o dump.o LIBS+=-lz obj-i386-$(CONFIG_KVM) += hyperv.o
dump.c new file +828 -0
828 lines not on this page · raw message
elf.h +5 -0
@@ -1016,6 +1016,11 @@ typedef struct elf64_sym {#define EI_NIDENT 16 +/* Special value for e_phnum. This indicates that the real number of +program headers is too large to fit into e_phnum. Instead the real +value is in the field sh_info of section 0. */ +#define PN_XNUM 0xffff + typedef struct elf32_hdr{ unsigned char e_ident[EI_NIDENT]; Elf32_Half e_type;
hmp-commands.hx +28 -0
@@ -879,6 +879,34 @@ server will ask the spice/vnc client to automatically reconnect using the new parameters (if specified) once the vm migration finished successfully. ETEXI +#if defined(CONFIG_HAVE_CORE_DUMP) + { + .name = "dump-guest-memory", + .args_type = "paging:-p,protocol:s,begin:i?,length:i?", + .params = "[-p] protocol [begin] [length]", + .help = "dump guest memory to file" + "\n\t\t\t begin(optional): the starting physical address" + "\n\t\t\t length(optional): the memory size, in bytes", + .user_print = monitor_user_noop, + .mhandler.cmd = hmp_dump_guest_memory, + }, + + +STEXI +@item dump-guest-memory [-p] @var{protocol} @var{begin} @var{length} +@findex dump-guest-memory +Dump guest memory to @var{protocol}. The file can be processed with crash or +gdb. + protocol: destination file(started with "file:") or destination file + descriptor (started with "fd:") + paging: do paging to get guest's memory mapping + begin: the starting physical address. It's optional, and should be + specified with length together. + length: the memory size, in bytes. It's optional, and should be specified + with begin together. +ETEXI +#endif + { .name = "snapshot_blkdev", .args_type = "reuse:-n,device:B,snapshot-file:s?,format:s?",
hmp.c +22 -0
@@ -934,3 +934,25 @@ void hmp_migrate(Monitor *mon, const QDict *qdict)qemu_mod_timer (status->timer,qemu_get_clock_ms (rt_clock)); } } + +void hmp_dump_guest_memory (Monitor *mon,const QDict *qdict) +{ +Error *errp =NULL ; +int paging =qdict_get_try_bool (qdict,"paging" ,0 ); +const char *file =qdict_get_str (qdict,"protocol" ); +bool has_begin =qdict_haskey (qdict,"begin" ); +bool has_length =qdict_haskey (qdict,"length" ); +int64_t begin =0 ; +int64_t length =0 ; + +if (has_begin) { + begin =qdict_get_int (qdict,"begin" ); + } +if (has_length) { + length =qdict_get_int (qdict,"length" ); + } + +qmp_dump_guest_memory (paging, file, has_begin, begin, has_length, length, + &errp); +hmp_handle_error (mon, &errp); +}
hmp.h +1 -0
@@ -60,5 +60,6 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict);void hmp_block_job_set_speed (Monitor *mon,const QDict *qdict);void hmp_block_job_cancel (Monitor *mon,const QDict *qdict);void hmp_migrate (Monitor *mon,const QDict *qdict); +void hmp_dump_guest_memory (Monitor *mon,const QDict *qdict);#endif
memory_mapping.c +27 -0
@@ -220,3 +220,30 @@ void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list)create_new_memory_mapping (list, block->offset,0 , block->length); } } + +void memory_mapping_filter (MemoryMappingList *list,int64_t begin, +int64_t length) +{ +MemoryMapping *cur, *next; + + QTAILQ_FOREACH_SAFE(cur, &list->head, next, next) { +if (cur->phys_addr >= begin + length || + cur->phys_addr + cur->length <= begin) { +QTAILQ_REMOVE (&list->head, cur, next); + list->num--; +continue ; + } + +if (cur->phys_addr < begin) { + cur->length -= begin - cur->phys_addr; +if (cur->virt_addr) { + cur->virt_addr += begin - cur->phys_addr; + } + cur->phys_addr = begin; + } + +if (cur->phys_addr + cur->length > begin + length) { + cur->length -= cur->phys_addr + cur->length - begin - length; + } + } +}
memory_mapping.h +3 -0
@@ -62,4 +62,7 @@ static inline int qemu_get_guest_memory_mapping(MemoryMappingList *list)/* get guest's memory mapping without do paging(virtual address is 0). */ void qemu_get_guest_simple_memory_mapping (MemoryMappingList *list); +void memory_mapping_filter (MemoryMappingList *list,int64_t begin, +int64_t length); +#endif
qapi-schema.json +34 -0
@@ -1701,3 +1701,37 @@ # Since: 1.1 ## { 'command': 'xen-save-devices-state', 'data': {'filename': 'str'} } + +## +# @dump-guest-memory +# +# Dump guest's memory to vmcore. +# +# @paging: if true, do paging to get guest's memory mapping. The @paging's +# default value of @paging is false, If you want to use gdb to process the +# core, please set @paging to true. The reason why the @paging's value is +# false: +# 1. guest machine in a catastrophic state can have corrupted memory, +# which we cannot trust. +# 2. The guest machine can be in read-mode even if paging is enabled. +# For example: the guest machine uses ACPI to sleep, and ACPI sleep +# state goes in real-mode +# @protocol: the filename or file descriptor of the vmcore. The supported +# protocol can be file or fd: +# 1. file: the protocol starts with "file:", and the following string is +# the file's path. +# 2. fd: the protocol starts with "fd:", and the following string is the +# fd's name. This command doesn't support the fd that is is associated +# with a pipe, socket, or FIFO(lseek will fail with such fd). +# @begin: #optional if specified, the starting physical address. +# @length: #optional if specified, the memory size, in bytes. If you don't +# want to dump all guest's memory, please specify the start @begin and +# @length +# +# Returns: nothing on success +# +# Since: 1.1 +## +{ 'command': 'dump-guest-memory', + 'data': { 'paging': 'bool', 'protocol': 'str', '*begin': 'int', + '*length': 'int' } }
qmp-commands.hx +38 -0
@@ -606,6 +606,44 @@ Example: EQMP +#if defined(CONFIG_HAVE_CORE_DUMP) + { + .name = "dump-guest-memory", + .args_type = "paging:b,protocol:s,begin:i?,end:i?", + .params = "[-p] protocol [begin] [length]", + .help = "dump guest memory to file", + .user_print = monitor_user_noop, + .mhandler.cmd_new = qmp_marshal_input_dump_guest_memory, + }, + +SQMP +dump + + +Dump guest memory to file. The file can be processed with crash or gdb. + +Arguments: + +- "paging": do paging to get guest's memory mapping (json-bool) +- "protocol": destination file(started with "file:") or destination file + descriptor (started with "fd:") (json-string) +- "begin": the starting physical address. It's optional, and should be specified + with length together (json-int) +- "length": the memory size, in bytes. It's optional, and should be specified + with begin together (json-int) + +Example: + +-> { "execute": "dump-guest-memory", "arguments": { "protocol": "fd:dump" } } +<- { "return": {} } + +Notes: + +(1) All boolean arguments default to false + +EQMP +#endif + { .name = "netdev_add", .args_type = "netdev:O",
Signature · 1 line
1.7.1
Hi, Luiz, Anthony, Jan
do you have any comments about this patchset?
Thanks
Wen Congyang
At 03/26/2012 05:58 PM, Wen Congyang Wrote:
Quoted 113 lines
Hi, all
'virsh dump' can not work when host pci device is used by guest. We have discussed this issue here:
http://lists.nongnu.org/archive/html/qemu-devel/2011-10/msg00736.htmlThe last version is here:
http://lists.nongnu.org/archive/html/qemu-devel/2012-03/msg03866.htmlWe have determined to introduce a new command dump-guest-memory to dump guest's memory. The core file's format is elf32 or elf64.
Note:
1. The guest should be x86 orx86_64. The other arch is not supported now.
2. If you use old gdb, gdb may crash. I use gdb-7.3.1, and it does not crash.
3. If the OS is in the second kernel, gdb may not work well, and crash can work by specifying '--machdep phys_addr=xxx' in the command line. The reason is that the second kernel will update the page table, and we can not get the page table for the first kernel.
4. The cpu's state is stored in QEMU note. You neet to modify crash to use it to calculatephys_base.
5. If the guest OS is 32 bit and the memory size is larger than 4G, the vmcore is elf64 format. You should use the gdb which is built with --enable-64-bit-bfd.
6. This patchset is based on the upstream tree, and apply one patch that is still in Luiz Capitulino's tree, because I use the APIqemu_get_fd()in this patchset.Changes from v10 to v11:
1. addressed Luiz's and Hatayam's comment
2. fix a bug about filtering featureChanges from v9 to v10:
1. fix some bug
2. addressed Luiz's and Hatayam's comment
3. remove cancel and query commandChanges from v8 to v9:
1. remove async support(it will be reimplemented after QAPI async commands support is finished)
2. fix some typo errorChanges from v7 to v8:
1. addressed Hatayama's commentsChanges from v6 to v7:
1. addressed Jan's comments
2. fix some bugs
3. store cpu's state into the vmcoreChanges from v5 to v6:
1. allow user to dump a fraction of the memory
2. fix some bugsChanges from v4 to v5:
1. convert the new command dump to QAPIChanges from v3 to v4:
1. support it to run asynchronously
2. add API to cancel dumping and query dumping progress
3. add API to control dumping speed
4. auto cancel dumping when the user resumes vm, and the status is failed.Changes from v2 to v3:
1. address Jan Kiszka's commentChanges from v1 to v2:
1. fix virt addr in the vmcore.Wen Congyang (12):
Add API to create memory mapping list
Add API to check whether a physical address is I/O address implementcpu_get_memory_mapping()
Add API to check whether paging mode is enabled
Add API to get memory mapping
Add API to get memory mapping without do paging
target-i386: Add API to write elf notes to core file
target-i386: Add API to write cpu status to core file
target-i386: add API to get dump info
makegdb_id()generally avialable and rename it tocpu_index()
QError: Introduce new error for the dump-guest-memory command introduce a new monitor command 'dump-guest-memory' to dump guest's
memoryMakefile.target | 3 + configure | 8 + cpu-all.h | 67 +++ cpu-common.h | 2 + dump.c | 827 +++++++++++++++++++++++++++++++++++++ dump.h | 23 + elf.h | 5 + exec.c | 9 + gdbstub.c | 19 +- gdbstub.h | 9 + hmp-commands.hx | 28 ++ hmp.c | 22 + hmp.h | 1 + memory_mapping.c | 236 +++++++++++ memory_mapping.h | 68 +++ qapi-schema.json | 34 ++ qerror.c | 4 + qerror.h | 3 + qmp-commands.hx | 38 ++ target-i386/arch_dump.c | 426 +++++++++++++++++++ target-i386/arch_memory_mapping.c | 271 ++++++++++++ 21 files changed, 2089 insertions(+), 14 deletions(-) create mode 100644 dump.c create mode 100644 dump.h create mode 100644 memory_mapping.c create mode 100644 memory_mapping.h create mode 100644 target-i386/arch_dump.c create mode 100644 target-i386/arch_memory_mapping.c
Luiz Capitulino
Acked-byQuoted 3 lines · On Wed, 28 Mar 2012 13:17:43 +0800 Wen Congyang <[email protected]> wrote:
Hi, Luiz, Anthony, Jan
do you have any comments about this patchset?
As far as QMP is concerned:
This can go through me tree, but I'd like an ACK from Jan and/or Anthony.
At 03/28/2012 08:44 PM, Luiz Capitulino Wrote:
Quoted 10 lines
Quoted 3 lines · On Wed, 28 Mar 2012 13:17:43 +0800 Wen Congyang <[email protected]> wrote:
Hi, Luiz, Anthony, Jan
do you have any comments about this patchset?
As far as QMP is concerned:
Acked-by Luiz Capitulino <[email protected]>
I fix a overflow bug and resend patch 12/12
Quoted 3 lines
This can go through me tree, but I'd like an ACK from Jan and/or Anthony.
Hi, Jan, Anthony
when do you have tiem to review this patchset?
Thanks
Wen Congyang
Quoted 15 lines · Wen Congyang
At 03/28/2012 08:44 PM, Luiz Capitulino Wrote:
Quoted 10 lines
Quoted 3 lines · On Wed, 28 Mar 2012 13:17:43 +0800 Wen Congyang <[email protected]> wrote:
Hi, Luiz, Anthony, Jan
do you have any comments about this patchset?
As far as QMP is concerned:
Acked-by Luiz Capitulino <[email protected]>I fix a overflow bug and resend patch 12/12
Quoted 1 line
Quoted 6 lines
Quoted 2 lines
This can go through me tree, but I'd like an ACK from Jan and/or Anthony.
Hi, Jan, Anthony
when do you have tiem to review this patchset?
High on my to-do list. I hope to have a look and a try the next days. Sorry for the long delay.
Jan
Signature · 2 lines
Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux