mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 23:33:54 -06:00
memory: add ref/unref calls
Add ref/unref calls at the following places: - places where memory regions are stashed by a listener and used outside the BQL (including in Xen or KVM). - memory_region_find callsites - creation of aliases and containers (only the aliased/contained region gets a reference to avoid loops) - around calls to del_subregion/add_subregion, where the region could disappear after the first call Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
3ce10901ca
commit
dfde4e6e1a
16 changed files with 63 additions and 5 deletions
21
memory.c
21
memory.c
|
@ -148,6 +148,7 @@ static bool memory_listener_match(MemoryListener *listener,
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
/* No need to ref/unref .mr, the FlatRange keeps it alive. */
|
||||
#define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback) \
|
||||
MEMORY_LISTENER_CALL(callback, dir, (&(MemoryRegionSection) { \
|
||||
.mr = (fr)->mr, \
|
||||
|
@ -263,11 +264,17 @@ static void flatview_insert(FlatView *view, unsigned pos, FlatRange *range)
|
|||
memmove(view->ranges + pos + 1, view->ranges + pos,
|
||||
(view->nr - pos) * sizeof(FlatRange));
|
||||
view->ranges[pos] = *range;
|
||||
memory_region_ref(range->mr);
|
||||
++view->nr;
|
||||
}
|
||||
|
||||
static void flatview_destroy(FlatView *view)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < view->nr; i++) {
|
||||
memory_region_unref(view->ranges[i].mr);
|
||||
}
|
||||
g_free(view->ranges);
|
||||
}
|
||||
|
||||
|
@ -709,6 +716,11 @@ static void memory_region_destructor_ram(MemoryRegion *mr)
|
|||
qemu_ram_free(mr->ram_addr);
|
||||
}
|
||||
|
||||
static void memory_region_destructor_alias(MemoryRegion *mr)
|
||||
{
|
||||
memory_region_unref(mr->alias);
|
||||
}
|
||||
|
||||
static void memory_region_destructor_ram_from_ptr(MemoryRegion *mr)
|
||||
{
|
||||
qemu_ram_free_from_ptr(mr->ram_addr);
|
||||
|
@ -964,6 +976,8 @@ void memory_region_init_alias(MemoryRegion *mr,
|
|||
uint64_t size)
|
||||
{
|
||||
memory_region_init(mr, owner, name, size);
|
||||
memory_region_ref(orig);
|
||||
mr->destructor = memory_region_destructor_alias;
|
||||
mr->alias = orig;
|
||||
mr->alias_offset = offset;
|
||||
}
|
||||
|
@ -1342,6 +1356,7 @@ static void memory_region_add_subregion_common(MemoryRegion *mr,
|
|||
memory_region_transaction_begin();
|
||||
|
||||
assert(!subregion->parent);
|
||||
memory_region_ref(subregion);
|
||||
subregion->parent = mr;
|
||||
subregion->addr = offset;
|
||||
QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
|
||||
|
@ -1404,6 +1419,7 @@ void memory_region_del_subregion(MemoryRegion *mr,
|
|||
assert(subregion->parent == mr);
|
||||
subregion->parent = NULL;
|
||||
QTAILQ_REMOVE(&mr->subregions, subregion, subregions_link);
|
||||
memory_region_unref(subregion);
|
||||
memory_region_update_pending |= mr->enabled && subregion->enabled;
|
||||
memory_region_transaction_commit();
|
||||
}
|
||||
|
@ -1431,12 +1447,14 @@ void memory_region_set_address(MemoryRegion *mr, hwaddr addr)
|
|||
}
|
||||
|
||||
memory_region_transaction_begin();
|
||||
memory_region_ref(mr);
|
||||
memory_region_del_subregion(parent, mr);
|
||||
if (may_overlap) {
|
||||
memory_region_add_subregion_overlap(parent, addr, mr, priority);
|
||||
} else {
|
||||
memory_region_add_subregion(parent, addr, mr);
|
||||
}
|
||||
memory_region_unref(mr);
|
||||
memory_region_transaction_commit();
|
||||
}
|
||||
|
||||
|
@ -1484,6 +1502,7 @@ bool memory_region_present(MemoryRegion *parent, hwaddr addr)
|
|||
if (!mr) {
|
||||
return false;
|
||||
}
|
||||
memory_region_unref(mr);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1523,6 +1542,8 @@ MemoryRegionSection memory_region_find(MemoryRegion *mr,
|
|||
ret.size = range.size;
|
||||
ret.offset_within_address_space = int128_get64(range.start);
|
||||
ret.readonly = fr->readonly;
|
||||
memory_region_ref(ret.mr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue