memory: add address_space_destroy()

Since address spaces can be created dynamically by device hotplug, they
can also be destroyed dynamically.

Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
Avi Kivity 2012-10-07 12:59:55 +02:00
parent b90600eed3
commit 83f3c25142
4 changed files with 39 additions and 2 deletions

10
exec.c
View File

@ -3234,6 +3234,16 @@ void address_space_init_dispatch(AddressSpace *as)
memory_listener_register(&d->listener, 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) static void memory_map_init(void)
{ {
system_memory = g_malloc(sizeof(*system_memory)); system_memory = g_malloc(sizeof(*system_memory));

View File

@ -41,6 +41,7 @@ struct AddressSpaceDispatch {
}; };
void address_space_init_dispatch(AddressSpace *as); 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, ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t size, void *host,
MemoryRegion *mr); MemoryRegion *mr);

View File

@ -564,8 +564,10 @@ static FlatView generate_memory_topology(MemoryRegion *mr)
flatview_init(&view); flatview_init(&view);
render_memory_region(&view, mr, int128_zero(), if (mr) {
addrrange_make(int128_zero(), int128_2_64()), false); render_memory_region(&view, mr, int128_zero(),
addrrange_make(int128_zero(), int128_2_64()), false);
}
flatview_simplify(&view); flatview_simplify(&view);
return view; return view;
@ -1542,6 +1544,18 @@ void address_space_init(AddressSpace *as, MemoryRegion *root)
address_space_init_dispatch(as); 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) uint64_t io_mem_read(MemoryRegion *mr, target_phys_addr_t addr, unsigned size)
{ {
return memory_region_dispatch_read(mr, addr, size); return memory_region_dispatch_read(mr, addr, size);

View File

@ -804,6 +804,18 @@ void mtree_info(fprintf_function mon_printf, void *f);
*/ */
void address_space_init(AddressSpace *as, MemoryRegion *root); 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. * address_space_rw: read from or write to an address space.
* *