In case one wants to create a permanent copy of a MemoryRegionSections, one needs access to flatview_ref()/flatview_unref(). Instead of exposing these, let's just add helpers to copy/free a MemoryRegionSection and properly adjust references.
Cc: Paolo Bonzini <[email protected]> Cc: "Michael S. Tsirkin" <[email protected]> Cc: Alex Williamson <[email protected]> Cc: Dr. David Alan Gilbert <[email protected]> Cc: Igor Mammedov <[email protected]> Cc: Pankaj Gupta <[email protected]> Cc: Peter Xu <[email protected]> Cc: Auger Eric <[email protected]> Cc: Wei Yang <[email protected]> Cc: teawater <[email protected]> Cc: Marek Kedzierski <[email protected]> Signed-off-by: David Hildenbrand <[email protected]> --- include/exec/memory.h | 20 ++++++++++++++++++++ softmmu/memory.c | 27 +++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/include/exec/memory.h b/include/exec/memory.h index 3ff36a9006..ad5e0d6278 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1023,6 +1023,26 @@ static inline bool MemoryRegionSection_eq(MemoryRegionSection *a, a->nonvolatile == b->nonvolatile; } +/** + * memory_region_section_new_copy: Copy a memory region section + * + * Allocate memory for a new copy, copy the memory region section, and + * properly take a reference on all relevant members. + * + * @s: the #MemoryRegionSection to copy + */ +MemoryRegionSection *memory_region_section_new_copy(MemoryRegionSection *s); + +/** + * memory_region_section_new_copy: Free a copied memory region section + * + * Free a copy of a memory section created via memory_region_section_new_copy(). + * properly dropping references on all relevant members. + * + * @s: the #MemoryRegionSection to copy + */ +void memory_region_section_free_copy(MemoryRegionSection *s); + /** * memory_region_init: Initialize a memory region * diff --git a/softmmu/memory.c b/softmmu/memory.c index fa4f0fa4a3..edc6c8a29d 100644 --- a/softmmu/memory.c +++ b/softmmu/memory.c @@ -2693,6 +2693,33 @@ MemoryRegionSection memory_region_find(MemoryRegion *mr, return ret; } +MemoryRegionSection *memory_region_section_new_copy(MemoryRegionSection *s) +{ + MemoryRegionSection *tmp = g_new(MemoryRegionSection, 1); + + *tmp = *s; + if (tmp->mr) { + memory_region_ref(tmp->mr); + } + if (tmp->fv) { + bool ret = flatview_ref(tmp->fv); + + g_assert(ret); + } + return tmp; +} + +void memory_region_section_free_copy(MemoryRegionSection *s) +{ + if (s->fv) { + flatview_unref(s->fv); + } + if (s->mr) { + memory_region_unref(s->mr); + } + g_free(s); +} + bool memory_region_present(MemoryRegion *container, hwaddr addr) { MemoryRegion *mr; -- 2.29.2
