From: Wen Congyang <we...@cn.fujitsu.com> Subject: [PATCH 05/11 v10] Add API to get memory mapping Date: Tue, 20 Mar 2012 11:51:18 +0800
> 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. > > Signed-off-by: Wen Congyang <we...@cn.fujitsu.com> > --- > memory_mapping.c | 34 ++++++++++++++++++++++++++++++++++ > memory_mapping.h | 15 +++++++++++++++ > 2 files changed, 49 insertions(+), 0 deletions(-) > > diff --git a/memory_mapping.c b/memory_mapping.c > index 718f271..b92e2f6 100644 > --- a/memory_mapping.c > +++ b/memory_mapping.c > @@ -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) { On SMP with (n)-CPUs, we can do this check at most (n)-times. On Linux, user-mode tasks have differnet page tables. If refering to one page table, we can get one user-mode task memory only. Considering as much memory as possible, it's best to reference all CPUs with paging enabled and walk all the page tables. A problem is that linear addresses for user-mode tasks can inherently conflicts. Different user-mode tasks can have the same linear address. So, tools need to distinguish each PT_LOAD entry based on a pair of linear address and physical address, not linear address only. I don't know whether gdb does this. > + 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. > + */ IIRC, ACPI sleep state goes in real-mode. There might be another that can go in real-mode. If execution enters this path in such situation, linear addresses are meaningless. But this is really rare case. > + QLIST_FOREACH(block, &ram_list.blocks, next) { > + offset = block->offset; > + length = block->length; > + create_new_memory_mapping(list, offset, offset, length); > + } > + > + return 0; > +} Thanks. HATAYAMA, Daisuke