mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 07:13:54 -06:00
memory: prepare for multiple bits in the dirty log mask
When the dirty log mask will also cover other bits than DIRTY_MEMORY_VGA, some listeners may be interested in the overall zero/non-zero value of the dirty log mask; others may be interested in the value of single bits. For this reason, always call log_start/log_stop if bits have respectively appeared or disappeared, and pass the old and new values of the dirty log mask so that listeners can distinguish the kinds of change. For example, KVM checks if dirty logging used to be completely disabled (in log_start) or is now completely disabled (in log_stop). On the other hand, Xen has to check manually if DIRTY_MEMORY_VGA changed, since that is the only bit it cares about. Reviewed-by: Fam Zheng <famz@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
2d1a35bef0
commit
b2dfd71c48
5 changed files with 44 additions and 19 deletions
17
memory.c
17
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue