KVM: Disable manual dirty log when dirty ring enabled
KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is for KVM_CLEAR_DIRTY_LOG, which is only useful for KVM_GET_DIRTY_LOG. Skip enabling it for kvm dirty ring. More importantly, KVM_DIRTY_LOG_INITIALLY_SET will not wr-protect all the pages initially, which is against how kvm dirty ring is used - there's no way for kvm dirty ring to re-protect a page before it's notified as being written first with a GFN entry in the ring! So when KVM_DIRTY_LOG_INITIALLY_SET is enabled with dirty ring, we'll see silent data loss after migration. Signed-off-by: Peter Xu <peterx@redhat.com> Message-Id: <20210506160549.130416-10-peterx@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
2ea5cb0a47
commit
a81a592698
@ -2131,20 +2131,29 @@ static int kvm_init(MachineState *ms)
|
|||||||
s->coalesced_pio = s->coalesced_mmio &&
|
s->coalesced_pio = s->coalesced_mmio &&
|
||||||
kvm_check_extension(s, KVM_CAP_COALESCED_PIO);
|
kvm_check_extension(s, KVM_CAP_COALESCED_PIO);
|
||||||
|
|
||||||
dirty_log_manual_caps =
|
/*
|
||||||
kvm_check_extension(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2);
|
* KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 is not needed when dirty ring is
|
||||||
dirty_log_manual_caps &= (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE |
|
* enabled. More importantly, KVM_DIRTY_LOG_INITIALLY_SET will assume no
|
||||||
KVM_DIRTY_LOG_INITIALLY_SET);
|
* page is wr-protected initially, which is against how kvm dirty ring is
|
||||||
s->manual_dirty_log_protect = dirty_log_manual_caps;
|
* usage - kvm dirty ring requires all pages are wr-protected at the very
|
||||||
if (dirty_log_manual_caps) {
|
* beginning. Enabling this feature for dirty ring causes data corruption.
|
||||||
ret = kvm_vm_enable_cap(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, 0,
|
*/
|
||||||
dirty_log_manual_caps);
|
if (!s->kvm_dirty_ring_size) {
|
||||||
if (ret) {
|
dirty_log_manual_caps =
|
||||||
warn_report("Trying to enable capability %"PRIu64" of "
|
kvm_check_extension(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2);
|
||||||
"KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 but failed. "
|
dirty_log_manual_caps &= (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE |
|
||||||
"Falling back to the legacy mode. ",
|
KVM_DIRTY_LOG_INITIALLY_SET);
|
||||||
dirty_log_manual_caps);
|
s->manual_dirty_log_protect = dirty_log_manual_caps;
|
||||||
s->manual_dirty_log_protect = 0;
|
if (dirty_log_manual_caps) {
|
||||||
|
ret = kvm_vm_enable_cap(s, KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2, 0,
|
||||||
|
dirty_log_manual_caps);
|
||||||
|
if (ret) {
|
||||||
|
warn_report("Trying to enable capability %"PRIu64" of "
|
||||||
|
"KVM_CAP_MANUAL_DIRTY_LOG_PROTECT2 but failed. "
|
||||||
|
"Falling back to the legacy mode. ",
|
||||||
|
dirty_log_manual_caps);
|
||||||
|
s->manual_dirty_log_protect = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user