Add API to get all virtual address and physical address mapping. If there is no virtual address for some physical address, the virtual address is 0.
Signed-off-by: Wen Congyang <we...@cn.fujitsu.com> --- memory_mapping.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ memory_mapping.h | 8 ++++++ 2 files changed, 79 insertions(+), 0 deletions(-) diff --git a/memory_mapping.c b/memory_mapping.c index 84fb2c8..3743805 100644 --- a/memory_mapping.c +++ b/memory_mapping.c @@ -132,3 +132,74 @@ void memory_mapping_list_init(MemoryMappingList *list) list->last_mapping = NULL; QTAILQ_INIT(&list->head); } + +int qemu_get_guest_memory_mapping(MemoryMappingList *list) +{ + CPUState *env; + MemoryMapping *memory_mapping; + RAMBlock *block; + ram_addr_t offset, length; + int ret; + +#if defined(CONFIG_HAVE_GET_MEMORY_MAPPING) + for (env = first_cpu; env != NULL; env = env->next_cpu) { + ret = cpu_get_memory_mapping(list, env); + if (ret < 0) { + return -1; + } + } +#else + return -2; +#endif + + /* some memory may be not mapped, add them into memory mapping's list */ + QLIST_FOREACH(block, &ram_list.blocks, next) { + offset = block->offset; + length = block->length; + + QTAILQ_FOREACH(memory_mapping, &list->head, next) { + if (memory_mapping->phys_addr >= (offset + length)) { + /* + * memory_mapping's list does not conatin the region + * [offset, offset+length) + */ + create_new_memory_mapping(list, offset, 0, length); + length = 0; + break; + } + + if ((memory_mapping->phys_addr + memory_mapping->length) <= + offset) { + continue; + } + + if (memory_mapping->phys_addr > offset) { + /* + * memory_mapping's list does not conatin the region + * [offset, memory_mapping->phys_addr) + */ + create_new_memory_mapping(list, offset, 0, + memory_mapping->phys_addr - offset); + } + + if ((offset + length) <= + (memory_mapping->phys_addr + memory_mapping->length)) { + length = 0; + break; + } + length -= memory_mapping->phys_addr + memory_mapping->length - + offset; + offset = memory_mapping->phys_addr + memory_mapping->length; + } + + if (length > 0) { + /* + * memory_mapping's list does not conatin the region + * [offset, memory_mapping->phys_addr) + */ + create_new_memory_mapping(list, offset, 0, length); + } + } + + return 0; +} diff --git a/memory_mapping.h b/memory_mapping.h index 633fcb9..5760d1d 100644 --- a/memory_mapping.h +++ b/memory_mapping.h @@ -41,4 +41,12 @@ void memory_mapping_list_add_sorted(MemoryMappingList *list, void memory_mapping_list_free(MemoryMappingList *list); void memory_mapping_list_init(MemoryMappingList *list); +/* + * Return value: + * 0: success + * -1: failed + * -2: unsupported + */ +int qemu_get_guest_memory_mapping(MemoryMappingList *list); + #endif -- 1.7.1