}
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 */
}
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);
}
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) {
}
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) {
} 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), \
.size = (fr)->addr.size, \
.offset_within_address_space = int128_get64((fr)->addr.start), \
.readonly = (fr)->readonly, \
- }))
+ }), ##_args)
struct CoalescedMemoryRange {
AddrRange addr;
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);
}
}
}
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)