Skip to content

Commit c57351a

Browse files
Gavin ShanMarc Zyngier
authored andcommitted
KVM: Push dirty information unconditionally to backup bitmap
In mark_page_dirty_in_slot(), we bail out when no running vcpu exists and a running vcpu context is strictly required by architecture. It may cause backwards compatible issue. Currently, saving vgic/its tables is the only known case where no running vcpu context is expected. We may have other unknown cases where no running vcpu context exists and it's reported by the warning message and we bail out without pushing the dirty information to the backup bitmap. For this, the application is going to enable the backup bitmap for the unknown cases. However, the dirty information can't be pushed to the backup bitmap even though the backup bitmap is enabled for those unknown cases in the application, until the unknown cases are added to the allowed list of non-running vcpu context with extra code changes to the host kernel. In order to make the new application, where the backup bitmap has been enabled, to work with the unchanged host, we continue to push the dirty information to the backup bitmap instead of bailing out early. With the added check on 'memslot->dirty_bitmap' to mark_page_dirty_in_slot(), the kernel crash is avoided silently by the combined conditions: no running vcpu context, kvm_arch_allow_write_without_running_vcpu() returns 'true', and the backup bitmap (KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP) isn't enabled yet. Suggested-by: Sean Christopherson <[email protected]> Signed-off-by: Gavin Shan <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent dc6df7d commit c57351a

File tree

1 file changed

+2
-3
lines changed

1 file changed

+2
-3
lines changed

virt/kvm/kvm_main.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3308,8 +3308,7 @@ void mark_page_dirty_in_slot(struct kvm *kvm,
33083308
if (WARN_ON_ONCE(vcpu && vcpu->kvm != kvm))
33093309
return;
33103310

3311-
if (WARN_ON_ONCE(!kvm_arch_allow_write_without_running_vcpu(kvm) && !vcpu))
3312-
return;
3311+
WARN_ON_ONCE(!vcpu && !kvm_arch_allow_write_without_running_vcpu(kvm));
33133312
#endif
33143313

33153314
if (memslot && kvm_slot_dirty_track_enabled(memslot)) {
@@ -3318,7 +3317,7 @@ void mark_page_dirty_in_slot(struct kvm *kvm,
33183317

33193318
if (kvm->dirty_ring_size && vcpu)
33203319
kvm_dirty_ring_push(vcpu, slot, rel_gfn);
3321-
else
3320+
else if (memslot->dirty_bitmap)
33223321
set_bit_le(rel_gfn, memslot->dirty_bitmap);
33233322
}
33243323
}

0 commit comments

Comments
 (0)