From ad7ae63e924ae4157b503a84f3cabef2888ed0f3 Mon Sep 17 00:00:00 2001 From: Fish Date: Thu, 20 Oct 2016 03:33:37 -0700 Subject: [PATCH] Remove unmapped/freed memory regions from the object property list. This commit fixes the following issues: - Any unmapped/free'd memory regions (MemoryRegion instances) are not removed from the object property linked list of its owner (which is always qdev_get_machine(uc)). This issue makes adding new memory mapping by calling mem_map() or mem_map_ptr() slower as more and more memory pages are mapped and unmapped - yes, even if those memory pages are unmapped, they still impact the speed of future memory page mappings due to this issue. - FlatView is not reconstructed after a memory region is freed during unmapping, which leads to a use-after-free the next time a new memory region is mapped in address_space_update_topology(). --- qemu/aarch64.h | 1 - qemu/arm.h | 1 - qemu/header_gen.py | 1 - qemu/include/qom/object.h | 2 ++ qemu/m68k.h | 1 - qemu/memory.c | 6 ++++-- qemu/mips.h | 1 - qemu/mips64.h | 1 - qemu/mips64el.h | 1 - qemu/mipsel.h | 1 - qemu/powerpc.h | 2 +- qemu/qom/object.c | 2 +- qemu/sparc.h | 1 - qemu/sparc64.h | 1 - qemu/x86_64.h | 1 - 15 files changed, 8 insertions(+), 15 deletions(-) diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 54be2c19..e6a9675f 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -2176,7 +2176,6 @@ #define object_property_allow_set_link object_property_allow_set_link_aarch64 #define object_property_del object_property_del_aarch64 #define object_property_del_all object_property_del_all_aarch64 -#define object_property_del_child object_property_del_child_aarch64 #define object_property_find object_property_find_aarch64 #define object_property_get object_property_get_aarch64 #define object_property_get_bool object_property_get_bool_aarch64 diff --git a/qemu/arm.h b/qemu/arm.h index 87d1b19e..f365ad05 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -2176,7 +2176,6 @@ #define object_property_allow_set_link object_property_allow_set_link_arm #define object_property_del object_property_del_arm #define object_property_del_all object_property_del_all_arm -#define object_property_del_child object_property_del_child_arm #define object_property_find object_property_find_arm #define object_property_get object_property_get_arm #define object_property_get_bool object_property_get_bool_arm diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 983fdecb..166e419e 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -2182,7 +2182,6 @@ symbols = ( 'object_property_allow_set_link', 'object_property_del', 'object_property_del_all', - 'object_property_del_child', 'object_property_find', 'object_property_get', 'object_property_get_bool', diff --git a/qemu/include/qom/object.h b/qemu/include/qom/object.h index 001e6236..9aa312c1 100644 --- a/qemu/include/qom/object.h +++ b/qemu/include/qom/object.h @@ -810,6 +810,8 @@ ObjectProperty *object_property_add(Object *obj, const char *name, void object_property_del(struct uc_struct *uc, Object *obj, const char *name, Error **errp); +void object_property_del_child(struct uc_struct *uc, Object *obj, Object *child, Error **errp); + /** * object_property_find: * @obj: the object diff --git a/qemu/m68k.h b/qemu/m68k.h index 755e85ee..5b94d6bc 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -2176,7 +2176,6 @@ #define object_property_allow_set_link object_property_allow_set_link_m68k #define object_property_del object_property_del_m68k #define object_property_del_all object_property_del_all_m68k -#define object_property_del_child object_property_del_child_m68k #define object_property_find object_property_find_m68k #define object_property_get object_property_get_m68k #define object_property_get_bool object_property_get_bool_m68k diff --git a/qemu/memory.c b/qemu/memory.c index 84d650c7..453ddce1 100644 --- a/qemu/memory.c +++ b/qemu/memory.c @@ -66,6 +66,8 @@ MemoryRegion *memory_map_ptr(struct uc_struct *uc, hwaddr begin, size_t size, ui return ram; } +static void memory_region_update_container_subregions(MemoryRegion *subregion); + void memory_unmap(struct uc_struct *uc, MemoryRegion *mr) { int i; @@ -79,7 +81,6 @@ void memory_unmap(struct uc_struct *uc, MemoryRegion *mr) tlb_flush_page(uc->current_cpu, addr); } } - mr->enabled = false; memory_region_del_subregion(get_system_memory(uc), mr); for (i = 0; i < uc->mapped_block_count; i++) { @@ -94,6 +95,7 @@ void memory_unmap(struct uc_struct *uc, MemoryRegion *mr) g_free(mr->ioeventfds); g_free((char *)mr->name); mr->name = NULL; + object_property_del_child(mr->uc, qdev_get_machine(mr->uc), obj, &error_abort); break; } } @@ -105,7 +107,6 @@ int memory_free(struct uc_struct *uc) Object *obj; int i; - get_system_memory(uc)->enabled = false; for (i = 0; i < uc->mapped_block_count; i++) { mr = uc->mapped_blocks[i]; mr->enabled = false; @@ -115,6 +116,7 @@ int memory_free(struct uc_struct *uc) obj->ref = 1; obj->free = g_free; g_free(mr->ioeventfds); + object_property_del_child(mr->uc, qdev_get_machine(mr->uc), obj, &error_abort); } return 0; diff --git a/qemu/mips.h b/qemu/mips.h index fd2ad22f..42abe8e1 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -2176,7 +2176,6 @@ #define object_property_allow_set_link object_property_allow_set_link_mips #define object_property_del object_property_del_mips #define object_property_del_all object_property_del_all_mips -#define object_property_del_child object_property_del_child_mips #define object_property_find object_property_find_mips #define object_property_get object_property_get_mips #define object_property_get_bool object_property_get_bool_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 4c47a987..de543305 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -2176,7 +2176,6 @@ #define object_property_allow_set_link object_property_allow_set_link_mips64 #define object_property_del object_property_del_mips64 #define object_property_del_all object_property_del_all_mips64 -#define object_property_del_child object_property_del_child_mips64 #define object_property_find object_property_find_mips64 #define object_property_get object_property_get_mips64 #define object_property_get_bool object_property_get_bool_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 71a19f6a..e4373fed 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -2176,7 +2176,6 @@ #define object_property_allow_set_link object_property_allow_set_link_mips64el #define object_property_del object_property_del_mips64el #define object_property_del_all object_property_del_all_mips64el -#define object_property_del_child object_property_del_child_mips64el #define object_property_find object_property_find_mips64el #define object_property_get object_property_get_mips64el #define object_property_get_bool object_property_get_bool_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 7ce0bd75..434c1194 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -2176,7 +2176,6 @@ #define object_property_allow_set_link object_property_allow_set_link_mipsel #define object_property_del object_property_del_mipsel #define object_property_del_all object_property_del_all_mipsel -#define object_property_del_child object_property_del_child_mipsel #define object_property_find object_property_find_mipsel #define object_property_get object_property_get_mipsel #define object_property_get_bool object_property_get_bool_mipsel diff --git a/qemu/powerpc.h b/qemu/powerpc.h index 6b5e109d..d778f297 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -14,6 +14,7 @@ #define memory_map_ptr memory_map_ptr_powerpc #define memory_unmap memory_unmap_powerpc #define memory_free memory_free_powerpc +#define free_code_gen_buffer free_code_gen_buffer_powerpc #define helper_raise_exception helper_raise_exception_powerpc #define tcg_enabled tcg_enabled_powerpc #define tcg_exec_init tcg_exec_init_powerpc @@ -2175,7 +2176,6 @@ #define object_property_allow_set_link object_property_allow_set_link_powerpc #define object_property_del object_property_del_powerpc #define object_property_del_all object_property_del_all_powerpc -#define object_property_del_child object_property_del_child_powerpc #define object_property_find object_property_find_powerpc #define object_property_get object_property_get_powerpc #define object_property_get_bool object_property_get_bool_powerpc diff --git a/qemu/qom/object.c b/qemu/qom/object.c index aca451ba..71e4d5a9 100644 --- a/qemu/qom/object.c +++ b/qemu/qom/object.c @@ -371,7 +371,7 @@ static void object_property_del_all(struct uc_struct *uc, Object *obj) } } -static void object_property_del_child(struct uc_struct *uc, Object *obj, Object *child, Error **errp) +void object_property_del_child(struct uc_struct *uc, Object *obj, Object *child, Error **errp) { ObjectProperty *prop; diff --git a/qemu/sparc.h b/qemu/sparc.h index 5139c3ea..b9fe4297 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -2176,7 +2176,6 @@ #define object_property_allow_set_link object_property_allow_set_link_sparc #define object_property_del object_property_del_sparc #define object_property_del_all object_property_del_all_sparc -#define object_property_del_child object_property_del_child_sparc #define object_property_find object_property_find_sparc #define object_property_get object_property_get_sparc #define object_property_get_bool object_property_get_bool_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index a95aaab6..a34d4193 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -2176,7 +2176,6 @@ #define object_property_allow_set_link object_property_allow_set_link_sparc64 #define object_property_del object_property_del_sparc64 #define object_property_del_all object_property_del_all_sparc64 -#define object_property_del_child object_property_del_child_sparc64 #define object_property_find object_property_find_sparc64 #define object_property_get object_property_get_sparc64 #define object_property_get_bool object_property_get_bool_sparc64 diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 75a37221..32d1be77 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -2176,7 +2176,6 @@ #define object_property_allow_set_link object_property_allow_set_link_x86_64 #define object_property_del object_property_del_x86_64 #define object_property_del_all object_property_del_all_x86_64 -#define object_property_del_child object_property_del_child_x86_64 #define object_property_find object_property_find_x86_64 #define object_property_get object_property_get_x86_64 #define object_property_get_bool object_property_get_bool_x86_64