summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/virtio/vhost.c6
-rw-r--r--include/exec/memory.h6
-rw-r--r--kvm-all.c14
-rw-r--r--memory.c17
-rw-r--r--xen-hvm.c20
5 files changed, 44 insertions, 19 deletions
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 53d23d281d..a7fe3c5104 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -676,13 +676,15 @@ static void vhost_log_global_stop(MemoryListener *listener)
}
static void vhost_log_start(MemoryListener *listener,
- MemoryRegionSection *section)
+ MemoryRegionSection *section,
+ int old, int new)
{
/* FIXME: implement */
}
static void vhost_log_stop(MemoryListener *listener,
- MemoryRegionSection *section)
+ MemoryRegionSection *section,
+ int old, int new)
{
/* FIXME: implement */
}
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 156d506063..55dc11d55c 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -206,8 +206,10 @@ struct MemoryListener {
void (*region_add)(MemoryListener *listener, MemoryRegionSection *section);
void (*region_del)(MemoryListener *listener, MemoryRegionSection *section);
void (*region_nop)(MemoryListener *listener, MemoryRegionSection *section);
- void (*log_start)(MemoryListener *listener, MemoryRegionSection *section);
- void (*log_stop)(MemoryListener *listener, MemoryRegionSection *section);
+ void (*log_start)(MemoryListener *listener, MemoryRegionSection *section,
+ int old, int new);
+ void (*log_stop)(MemoryListener *listener, MemoryRegionSection *section,
+ int old, int new);
void (*log_sync)(MemoryListener *listener, MemoryRegionSection *section);
void (*log_global_start)(MemoryListener *listener);
void (*log_global_stop)(MemoryListener *listener);
diff --git a/kvm-all.c b/kvm-all.c
index d5416bbd74..c713b22f8c 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -344,10 +344,15 @@ static int kvm_dirty_pages_log_change(hwaddr phys_addr,
}
static void kvm_log_start(MemoryListener *listener,
- MemoryRegionSection *section)
+ MemoryRegionSection *section,
+ int old, int new)
{
int r;
+ if (old != 0) {
+ return;
+ }
+
r = kvm_dirty_pages_log_change(section->offset_within_address_space,
int128_get64(section->size), true);
if (r < 0) {
@@ -356,10 +361,15 @@ static void kvm_log_start(MemoryListener *listener,
}
static void kvm_log_stop(MemoryListener *listener,
- MemoryRegionSection *section)
+ MemoryRegionSection *section,
+ int old, int new)
{
int r;
+ if (new != 0) {
+ return;
+ }
+
r = kvm_dirty_pages_log_change(section->offset_within_address_space,
int128_get64(section->size), false);
if (r < 0) {
diff --git a/memory.c b/memory.c
index 72e33e853b..3e3d5b8ad6 100644
--- a/memory.c
+++ b/memory.c
@@ -152,7 +152,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) \
+#define MEMORY_LISTENER_UPDATE_REGION(fr, as, dir, callback, _args...) \
MEMORY_LISTENER_CALL(callback, dir, (&(MemoryRegionSection) { \
.mr = (fr)->mr, \
.address_space = (as), \
@@ -160,7 +160,7 @@ static bool memory_listener_match(MemoryListener *listener,
.size = (fr)->addr.size, \
.offset_within_address_space = int128_get64((fr)->addr.start), \
.readonly = (fr)->readonly, \
- }))
+ }), ##_args)
struct CoalescedMemoryRange {
AddrRange addr;
@@ -774,10 +774,15 @@ static void address_space_update_topology_pass(AddressSpace *as,
if (adding) {
MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, region_nop);
- if (frold->dirty_log_mask && !frnew->dirty_log_mask) {
- MEMORY_LISTENER_UPDATE_REGION(frnew, as, Reverse, log_stop);
- } else if (frnew->dirty_log_mask && !frold->dirty_log_mask) {
- MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, log_start);
+ if (frnew->dirty_log_mask & ~frold->dirty_log_mask) {
+ MEMORY_LISTENER_UPDATE_REGION(frnew, as, Forward, log_start,
+ frold->dirty_log_mask,
+ frnew->dirty_log_mask);
+ }
+ if (frold->dirty_log_mask & ~frnew->dirty_log_mask) {
+ MEMORY_LISTENER_UPDATE_REGION(frnew, as, Reverse, log_stop,
+ frold->dirty_log_mask,
+ frnew->dirty_log_mask);
}
}
diff --git a/xen-hvm.c b/xen-hvm.c
index 338ab291f8..42356b836a 100644
--- a/xen-hvm.c
+++ b/xen-hvm.c
@@ -646,21 +646,27 @@ static void xen_sync_dirty_bitmap(XenIOState *state,
}
static void xen_log_start(MemoryListener *listener,
- MemoryRegionSection *section)
+ MemoryRegionSection *section,
+ int old, int new)
{
XenIOState *state = container_of(listener, XenIOState, memory_listener);
- xen_sync_dirty_bitmap(state, section->offset_within_address_space,
- int128_get64(section->size));
+ if (new & ~old & (1 << DIRTY_MEMORY_VGA)) {
+ xen_sync_dirty_bitmap(state, section->offset_within_address_space,
+ int128_get64(section->size));
+ }
}
-static void xen_log_stop(MemoryListener *listener, MemoryRegionSection *section)
+static void xen_log_stop(MemoryListener *listener, MemoryRegionSection *section,
+ int old, int new)
{
XenIOState *state = container_of(listener, XenIOState, memory_listener);
- state->log_for_dirtybit = NULL;
- /* Disable dirty bit tracking */
- xc_hvm_track_dirty_vram(xen_xc, xen_domid, 0, 0, NULL);
+ if (old & ~new & (1 << DIRTY_MEMORY_VGA)) {
+ state->log_for_dirtybit = NULL;
+ /* Disable dirty bit tracking */
+ xc_hvm_track_dirty_vram(xen_xc, xen_domid, 0, 0, NULL);
+ }
}
static void xen_log_sync(MemoryListener *listener, MemoryRegionSection *section)