diff options
author | Richard Henderson | 2021-10-03 14:45:19 +0200 |
---|---|---|
committer | Richard Henderson | 2021-10-03 14:45:19 +0200 |
commit | 30bd1db58b09c12b68c35f041f919014b885482d (patch) | |
tree | 4acfdd873daa794d4144fffc2597d6f04360721f /softmmu/memory_mapping.c | |
parent | Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-10-02' into ... (diff) | |
parent | softmmu/memory_mapping: optimize for RamDiscardManager sections (diff) | |
download | qemu-30bd1db58b09c12b68c35f041f919014b885482d.tar.gz qemu-30bd1db58b09c12b68c35f041f919014b885482d.tar.xz qemu-30bd1db58b09c12b68c35f041f919014b885482d.zip |
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* -smp cleanpus (Yanan)
* Hyper-V enlightenment functionality (Vitaly)
* virtio-mem support in dump, tpm and QMP (David)
* NetBSD GCC 7.4 compiler support (Nia)
# gpg: Signature made Sun 03 Oct 2021 03:41:30 AM EDT
# gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83
# gpg: issuer "pbonzini@redhat.com"
# gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full]
# gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full]
* remotes/bonzini/tags/for-upstream:
softmmu/memory_mapping: optimize for RamDiscardManager sections
softmmu/memory_mapping: factor out adding physical memory ranges
softmmu/memory_mapping: never merge ranges accross memory regions
tpm: mark correct memory region range dirty when clearing RAM
monitor: Rate-limit MEMORY_DEVICE_SIZE_CHANGE qapi events per device
qapi: Include qom-path in MEMORY_DEVICE_SIZE_CHANGE qapi events
virtio-mem-pci: Fix memory leak when creating MEMORY_DEVICE_SIZE_CHANGE event
configure: Loosen GCC requirement from 7.5.0 to 7.4.0
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'softmmu/memory_mapping.c')
-rw-r--r-- | softmmu/memory_mapping.c | 64 |
1 files changed, 42 insertions, 22 deletions
diff --git a/softmmu/memory_mapping.c b/softmmu/memory_mapping.c index e7af276546..a62eaa49cc 100644 --- a/softmmu/memory_mapping.c +++ b/softmmu/memory_mapping.c @@ -193,29 +193,14 @@ typedef struct GuestPhysListener { MemoryListener listener; } GuestPhysListener; -static void guest_phys_blocks_region_add(MemoryListener *listener, +static void guest_phys_block_add_section(GuestPhysListener *g, MemoryRegionSection *section) { - GuestPhysListener *g; - uint64_t section_size; - hwaddr target_start, target_end; - uint8_t *host_addr; - GuestPhysBlock *predecessor; - - /* we only care about RAM */ - if (!memory_region_is_ram(section->mr) || - memory_region_is_ram_device(section->mr) || - memory_region_is_nonvolatile(section->mr)) { - return; - } - - g = container_of(listener, GuestPhysListener, listener); - section_size = int128_get64(section->size); - target_start = section->offset_within_address_space; - target_end = target_start + section_size; - host_addr = memory_region_get_ram_ptr(section->mr) + - section->offset_within_region; - predecessor = NULL; + const hwaddr target_start = section->offset_within_address_space; + const hwaddr target_end = target_start + int128_get64(section->size); + uint8_t *host_addr = memory_region_get_ram_ptr(section->mr) + + section->offset_within_region; + GuestPhysBlock *predecessor = NULL; /* find continuity in guest physical address space */ if (!QTAILQ_EMPTY(&g->list->head)) { @@ -229,7 +214,8 @@ static void guest_phys_blocks_region_add(MemoryListener *listener, /* we want continuity in both guest-physical and host-virtual memory */ if (predecessor->target_end < target_start || - predecessor->host_addr + predecessor_size != host_addr) { + predecessor->host_addr + predecessor_size != host_addr || + predecessor->mr != section->mr) { predecessor = NULL; } } @@ -260,6 +246,40 @@ static void guest_phys_blocks_region_add(MemoryListener *listener, #endif } +static int guest_phys_ram_populate_cb(MemoryRegionSection *section, + void *opaque) +{ + GuestPhysListener *g = opaque; + + guest_phys_block_add_section(g, section); + return 0; +} + +static void guest_phys_blocks_region_add(MemoryListener *listener, + MemoryRegionSection *section) +{ + GuestPhysListener *g = container_of(listener, GuestPhysListener, listener); + + /* we only care about RAM */ + if (!memory_region_is_ram(section->mr) || + memory_region_is_ram_device(section->mr) || + memory_region_is_nonvolatile(section->mr)) { + return; + } + + /* for special sparse regions, only add populated parts */ + if (memory_region_has_ram_discard_manager(section->mr)) { + RamDiscardManager *rdm; + + rdm = memory_region_get_ram_discard_manager(section->mr); + ram_discard_manager_replay_populated(rdm, section, + guest_phys_ram_populate_cb, g); + return; + } + + guest_phys_block_add_section(g, section); +} + void guest_phys_blocks_append(GuestPhysBlockList *list) { GuestPhysListener g = { 0 }; |