]> git.proxmox.com Git - qemu.git/commitdiff
memory: add address_space_destroy()
authorAvi Kivity <avi@redhat.com>
Sun, 7 Oct 2012 10:59:55 +0000 (12:59 +0200)
committerAvi Kivity <avi@redhat.com>
Mon, 22 Oct 2012 12:50:08 +0000 (14:50 +0200)
Since address spaces can be created dynamically by device hotplug, they
can also be destroyed dynamically.

Signed-off-by: Avi Kivity <avi@redhat.com>
exec.c
memory-internal.h
memory.c
memory.h

diff --git a/exec.c b/exec.c
index bfc4acc206318eeb296e4f3716f37b4c37bf42d2..17e8ba21d42249539bb2e9cf3abf482413b20550 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -3234,6 +3234,16 @@ void address_space_init_dispatch(AddressSpace *as)
     memory_listener_register(&d->listener, as);
 }
 
+void address_space_destroy_dispatch(AddressSpace *as)
+{
+    AddressSpaceDispatch *d = as->dispatch;
+
+    memory_listener_unregister(&d->listener);
+    destroy_l2_mapping(&d->phys_map, P_L2_LEVELS - 1);
+    g_free(d);
+    as->dispatch = NULL;
+}
+
 static void memory_map_init(void)
 {
     system_memory = g_malloc(sizeof(*system_memory));
index 6d8711bb1f702044fecde35c6679986ddad86a7c..4d33cc9530bcffb3f0b7acdd60e51d675d85b8e9 100644 (file)
@@ -41,6 +41,7 @@ struct AddressSpaceDispatch {
 };
 
 void address_space_init_dispatch(AddressSpace *as);
+void address_space_destroy_dispatch(AddressSpace *as);
 
 ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
                                    MemoryRegion *mr);
index 13be84849cd01b9917df35e5cd04b46702bcbd2f..2f68d67c215a28adc7b60e08e3f5240902aa6223 100644 (file)
--- a/memory.c
+++ b/memory.c
@@ -564,8 +564,10 @@ static FlatView generate_memory_topology(MemoryRegion *mr)
 
     flatview_init(&view);
 
-    render_memory_region(&view, mr, int128_zero(),
-                         addrrange_make(int128_zero(), int128_2_64()), false);
+    if (mr) {
+        render_memory_region(&view, mr, int128_zero(),
+                             addrrange_make(int128_zero(), int128_2_64()), false);
+    }
     flatview_simplify(&view);
 
     return view;
@@ -1542,6 +1544,18 @@ void address_space_init(AddressSpace *as, MemoryRegion *root)
     address_space_init_dispatch(as);
 }
 
+void address_space_destroy(AddressSpace *as)
+{
+    /* Flush out anything from MemoryListeners listening in on this */
+    memory_region_transaction_begin();
+    as->root = NULL;
+    memory_region_transaction_commit();
+    QTAILQ_REMOVE(&address_spaces, as, address_spaces_link);
+    address_space_destroy_dispatch(as);
+    flatview_destroy(as->current_map);
+    g_free(as->current_map);
+}
+
 uint64_t io_mem_read(MemoryRegion *mr, target_phys_addr_t addr, unsigned size)
 {
     return memory_region_dispatch_read(mr, addr, size);
index d36c2baa23d6b5366d014c88c9f165d8b086ea9a..79393f1a764afc652228d3ef73244eaf2ab299c7 100644 (file)
--- a/memory.h
+++ b/memory.h
@@ -804,6 +804,18 @@ void mtree_info(fprintf_function mon_printf, void *f);
  */
 void address_space_init(AddressSpace *as, MemoryRegion *root);
 
+
+/**
+ * address_space_destroy: destroy an address space
+ *
+ * Releases all resources associated with an address space.  After an address space
+ * is destroyed, its root memory region (given by address_space_init()) may be destroyed
+ * as well.
+ *
+ * @as: address space to be destroyed
+ */
+void address_space_destroy(AddressSpace *as);
+
 /**
  * address_space_rw: read from or write to an address space.
  *