aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/virtio/vhost.c4
-rw-r--r--memory.c27
2 files changed, 27 insertions, 4 deletions
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index c4f654c704..d16c0c813d 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -1368,10 +1368,6 @@ void vhost_dev_cleanup(struct vhost_dev *hdev)
if (hdev->mem) {
/* those are only safe after successful init */
memory_listener_unregister(&hdev->memory_listener);
- for (i = 0; i < hdev->n_mem_sections; ++i) {
- MemoryRegionSection *section = &hdev->mem_sections[i];
- memory_region_unref(section->mr);
- }
QLIST_REMOVE(hdev, entry);
}
if (hdev->migration_blocker) {
diff --git a/memory.c b/memory.c
index 9e8349668d..5686698542 100644
--- a/memory.c
+++ b/memory.c
@@ -2612,6 +2612,32 @@ static void listener_add_address_space(MemoryListener *listener,
flatview_unref(view);
}
+static void listener_del_address_space(MemoryListener *listener,
+ AddressSpace *as)
+{
+ FlatView *view;
+ FlatRange *fr;
+
+ if (listener->begin) {
+ listener->begin(listener);
+ }
+ view = address_space_get_flatview(as);
+ FOR_EACH_FLAT_RANGE(fr, view) {
+ MemoryRegionSection section = section_from_flat_range(fr, view);
+
+ if (fr->dirty_log_mask && listener->log_stop) {
+ listener->log_stop(listener, &section, fr->dirty_log_mask, 0);
+ }
+ if (listener->region_del) {
+ listener->region_del(listener, &section);
+ }
+ }
+ if (listener->commit) {
+ listener->commit(listener);
+ }
+ flatview_unref(view);
+}
+
void memory_listener_register(MemoryListener *listener, AddressSpace *as)
{
MemoryListener *other = NULL;
@@ -2652,6 +2678,7 @@ void memory_listener_unregister(MemoryListener *listener)
return;
}
+ listener_del_address_space(listener, listener->address_space);
QTAILQ_REMOVE(&memory_listeners, listener, link);
QTAILQ_REMOVE(&listener->address_space->listeners, listener, link_as);
listener->address_space = NULL;