mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-08 22:35:35 +00:00
memory: Add address_space_init_shareable()
This will either create a new AS or return a pointer to an already existing equivalent one, if we have already created an AS for the specified root memory region. The motivation is to reuse address spaces as much as possible. It's going to be quite common that bus masters out in device land have pointers to the same memory region for their mastering yet each will need to create its own address space. Let the memory API implement sharing for them. Aside from the perf optimisations, this should reduce the amount of redundant output on info mtree as well. Thee returned value will be malloced, but the malloc will be automatically freed when the AS runs out of refs. Backports commit f0c02d15b57da6f5463e3768aa0cfeedccf4b8f4 from qemu
This commit is contained in:
parent
73efe6cda3
commit
b82e711a65
|
@ -91,6 +91,7 @@
|
|||
#define address_space_get_flatview address_space_get_flatview_aarch64
|
||||
#define address_space_init address_space_init_aarch64
|
||||
#define address_space_init_dispatch address_space_init_dispatch_aarch64
|
||||
#define address_space_init_shareable address_space_init_shareable_aarch64
|
||||
#define address_space_lookup_region address_space_lookup_region_aarch64
|
||||
#define address_space_map address_space_map_aarch64
|
||||
#define address_space_read address_space_read_aarch64
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
#define address_space_get_flatview address_space_get_flatview_aarch64eb
|
||||
#define address_space_init address_space_init_aarch64eb
|
||||
#define address_space_init_dispatch address_space_init_dispatch_aarch64eb
|
||||
#define address_space_init_shareable address_space_init_shareable_aarch64eb
|
||||
#define address_space_lookup_region address_space_lookup_region_aarch64eb
|
||||
#define address_space_map address_space_map_aarch64eb
|
||||
#define address_space_read address_space_read_aarch64eb
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
#define address_space_get_flatview address_space_get_flatview_arm
|
||||
#define address_space_init address_space_init_arm
|
||||
#define address_space_init_dispatch address_space_init_dispatch_arm
|
||||
#define address_space_init_shareable address_space_init_shareable_arm
|
||||
#define address_space_lookup_region address_space_lookup_region_arm
|
||||
#define address_space_map address_space_map_arm
|
||||
#define address_space_read address_space_read_arm
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
#define address_space_get_flatview address_space_get_flatview_armeb
|
||||
#define address_space_init address_space_init_armeb
|
||||
#define address_space_init_dispatch address_space_init_dispatch_armeb
|
||||
#define address_space_init_shareable address_space_init_shareable_armeb
|
||||
#define address_space_lookup_region address_space_lookup_region_armeb
|
||||
#define address_space_map address_space_map_armeb
|
||||
#define address_space_read address_space_read_armeb
|
||||
|
|
|
@ -97,6 +97,7 @@ symbols = (
|
|||
'address_space_get_flatview',
|
||||
'address_space_init',
|
||||
'address_space_init_dispatch',
|
||||
'address_space_init_shareable',
|
||||
'address_space_lookup_region',
|
||||
'address_space_map',
|
||||
'address_space_read',
|
||||
|
|
|
@ -219,6 +219,8 @@ struct AddressSpace {
|
|||
/* All fields are private. */
|
||||
char *name;
|
||||
MemoryRegion *root;
|
||||
int ref_count;
|
||||
bool malloced;
|
||||
struct FlatView *current_map;
|
||||
struct AddressSpaceDispatch *dispatch;
|
||||
struct AddressSpaceDispatch *next_dispatch;
|
||||
|
@ -901,6 +903,23 @@ MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
|
|||
*/
|
||||
void address_space_init(struct uc_struct *uc, AddressSpace *as, MemoryRegion *root, const char *name);
|
||||
|
||||
/**
|
||||
* address_space_init_shareable: return an address space for a memory region,
|
||||
* creating it if it does not already exist
|
||||
*
|
||||
* @root: a #MemoryRegion that routes addresses for the address space
|
||||
* @name: an address space name. The name is only used for debugging
|
||||
* output.
|
||||
*
|
||||
* This function will return a pointer to an existing AddressSpace
|
||||
* which was initialized with the specified MemoryRegion, or it will
|
||||
* create and initialize one if it does not already exist. The ASes
|
||||
* are reference-counted, so the memory will be freed automatically
|
||||
* when the AddressSpace is destroyed via address_space_destroy.
|
||||
*/
|
||||
AddressSpace *address_space_init_shareable(struct uc_struct* uc,
|
||||
MemoryRegion *root,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* address_space_destroy: destroy an address space
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
#define address_space_get_flatview address_space_get_flatview_m68k
|
||||
#define address_space_init address_space_init_m68k
|
||||
#define address_space_init_dispatch address_space_init_dispatch_m68k
|
||||
#define address_space_init_shareable address_space_init_shareable_m68k
|
||||
#define address_space_lookup_region address_space_lookup_region_m68k
|
||||
#define address_space_map address_space_map_m68k
|
||||
#define address_space_read address_space_read_m68k
|
||||
|
|
|
@ -1679,8 +1679,10 @@ void address_space_init(struct uc_struct *uc, AddressSpace *as, MemoryRegion *ro
|
|||
}
|
||||
|
||||
memory_region_transaction_begin(uc);
|
||||
as->ref_count = 1;
|
||||
as->uc = uc;
|
||||
as->root = root;
|
||||
as->malloced = false;
|
||||
as->current_map = g_new(FlatView, 1);
|
||||
flatview_init(as->current_map);
|
||||
QTAILQ_INSERT_TAIL(&uc->address_spaces, as, address_spaces_link);
|
||||
|
@ -1690,9 +1692,53 @@ void address_space_init(struct uc_struct *uc, AddressSpace *as, MemoryRegion *ro
|
|||
memory_region_transaction_commit(uc);
|
||||
}
|
||||
|
||||
void address_space_destroy(AddressSpace *as)
|
||||
static void do_address_space_destroy(AddressSpace *as)
|
||||
{
|
||||
MemoryListener *listener;
|
||||
bool do_free = as->malloced;
|
||||
|
||||
address_space_destroy_dispatch(as);
|
||||
|
||||
// TODO(danghvu): why assert fail here?
|
||||
//QTAILQ_FOREACH(listener, &as->uc->memory_listeners, link) {
|
||||
// assert(listener->address_space_filter != as);
|
||||
//}
|
||||
|
||||
flatview_unref(as->current_map);
|
||||
g_free(as->name);
|
||||
// Unicorn: commented out
|
||||
//g_free(as->ioeventfds);
|
||||
memory_region_unref(as->root);
|
||||
if (do_free) {
|
||||
g_free(as);
|
||||
}
|
||||
}
|
||||
|
||||
AddressSpace *address_space_init_shareable(struct uc_struct *uc, MemoryRegion *root, const char *name)
|
||||
{
|
||||
AddressSpace *as;
|
||||
|
||||
QTAILQ_FOREACH(as, &uc->address_spaces, address_spaces_link) {
|
||||
if (root == as->root && as->malloced) {
|
||||
as->ref_count++;
|
||||
return as;
|
||||
}
|
||||
}
|
||||
|
||||
as = g_malloc0(sizeof *as);
|
||||
address_space_init(uc, as, root, name);
|
||||
as->malloced = true;
|
||||
return as;
|
||||
}
|
||||
|
||||
void address_space_destroy(AddressSpace *as)
|
||||
{
|
||||
MemoryRegion *root = as->root;
|
||||
|
||||
as->ref_count--;
|
||||
if (as->ref_count) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Flush out anything from MemoryListeners listening in on this */
|
||||
memory_region_transaction_begin(as->uc);
|
||||
|
@ -1701,15 +1747,15 @@ void address_space_destroy(AddressSpace *as)
|
|||
QTAILQ_REMOVE(&as->uc->address_spaces, as, address_spaces_link);
|
||||
address_space_unregister(as);
|
||||
|
||||
address_space_destroy_dispatch(as);
|
||||
/* At this point, as->dispatch and as->current_map are dummy
|
||||
* entries that the guest should never use. Wait for the old
|
||||
* values to expire before freeing the data.
|
||||
*/
|
||||
as->root = root;
|
||||
do_address_space_destroy(as);
|
||||
|
||||
// TODO(danghvu): why assert fail here?
|
||||
QTAILQ_FOREACH(listener, &as->uc->memory_listeners, link) {
|
||||
// assert(listener->address_space_filter != as);
|
||||
}
|
||||
|
||||
flatview_unref(as->current_map);
|
||||
g_free(as->name);
|
||||
// Unicorn: Commented out and call it directly
|
||||
// call_rcu(as, do_address_space_destroy, rcu);
|
||||
}
|
||||
|
||||
typedef struct MemoryRegionList MemoryRegionList;
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
#define address_space_get_flatview address_space_get_flatview_mips
|
||||
#define address_space_init address_space_init_mips
|
||||
#define address_space_init_dispatch address_space_init_dispatch_mips
|
||||
#define address_space_init_shareable address_space_init_shareable_mips
|
||||
#define address_space_lookup_region address_space_lookup_region_mips
|
||||
#define address_space_map address_space_map_mips
|
||||
#define address_space_read address_space_read_mips
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
#define address_space_get_flatview address_space_get_flatview_mips64
|
||||
#define address_space_init address_space_init_mips64
|
||||
#define address_space_init_dispatch address_space_init_dispatch_mips64
|
||||
#define address_space_init_shareable address_space_init_shareable_mips64
|
||||
#define address_space_lookup_region address_space_lookup_region_mips64
|
||||
#define address_space_map address_space_map_mips64
|
||||
#define address_space_read address_space_read_mips64
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
#define address_space_get_flatview address_space_get_flatview_mips64el
|
||||
#define address_space_init address_space_init_mips64el
|
||||
#define address_space_init_dispatch address_space_init_dispatch_mips64el
|
||||
#define address_space_init_shareable address_space_init_shareable_mips64el
|
||||
#define address_space_lookup_region address_space_lookup_region_mips64el
|
||||
#define address_space_map address_space_map_mips64el
|
||||
#define address_space_read address_space_read_mips64el
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
#define address_space_get_flatview address_space_get_flatview_mipsel
|
||||
#define address_space_init address_space_init_mipsel
|
||||
#define address_space_init_dispatch address_space_init_dispatch_mipsel
|
||||
#define address_space_init_shareable address_space_init_shareable_mipsel
|
||||
#define address_space_lookup_region address_space_lookup_region_mipsel
|
||||
#define address_space_map address_space_map_mipsel
|
||||
#define address_space_read address_space_read_mipsel
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
#define address_space_get_flatview address_space_get_flatview_powerpc
|
||||
#define address_space_init address_space_init_powerpc
|
||||
#define address_space_init_dispatch address_space_init_dispatch_powerpc
|
||||
#define address_space_init_shareable address_space_init_shareable_powerpc
|
||||
#define address_space_lookup_region address_space_lookup_region_powerpc
|
||||
#define address_space_map address_space_map_powerpc
|
||||
#define address_space_read address_space_read_powerpc
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
#define address_space_get_flatview address_space_get_flatview_sparc
|
||||
#define address_space_init address_space_init_sparc
|
||||
#define address_space_init_dispatch address_space_init_dispatch_sparc
|
||||
#define address_space_init_shareable address_space_init_shareable_sparc
|
||||
#define address_space_lookup_region address_space_lookup_region_sparc
|
||||
#define address_space_map address_space_map_sparc
|
||||
#define address_space_read address_space_read_sparc
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
#define address_space_get_flatview address_space_get_flatview_sparc64
|
||||
#define address_space_init address_space_init_sparc64
|
||||
#define address_space_init_dispatch address_space_init_dispatch_sparc64
|
||||
#define address_space_init_shareable address_space_init_shareable_sparc64
|
||||
#define address_space_lookup_region address_space_lookup_region_sparc64
|
||||
#define address_space_map address_space_map_sparc64
|
||||
#define address_space_read address_space_read_sparc64
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
#define address_space_get_flatview address_space_get_flatview_x86_64
|
||||
#define address_space_init address_space_init_x86_64
|
||||
#define address_space_init_dispatch address_space_init_dispatch_x86_64
|
||||
#define address_space_init_shareable address_space_init_shareable_x86_64
|
||||
#define address_space_lookup_region address_space_lookup_region_x86_64
|
||||
#define address_space_map address_space_map_x86_64
|
||||
#define address_space_read address_space_read_x86_64
|
||||
|
|
Loading…
Reference in a new issue