Commit 52f46079 authored by Sean Christopherson's avatar Sean Christopherson Committed by Paolo Bonzini
Browse files

KVM: x86: Further clarify the logic and comments for toggling log dirty



Add a sanity check in kvm_mmu_slot_apply_flags to assert that the
LOG_DIRTY_PAGES flag is indeed being toggled, and explicitly rely on
that holding true when zapping collapsible SPTEs.  Manipulating the
CPU dirty log (PML) and write-protection also relies on this assertion,
but that's not obvious in the current code.

Signed-off-by: default avatarSean Christopherson <seanjc@google.com>
Message-Id: <20210213005015.1651772-11-seanjc@google.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent a018eba5
Loading
Loading
Loading
Loading
+11 −4
Original line number Original line Diff line number Diff line
@@ -10761,12 +10761,20 @@ static void kvm_mmu_slot_apply_flags(struct kvm *kvm,
				     enum kvm_mr_change change)
				     enum kvm_mr_change change)
{
{
	/*
	/*
	 * Nothing to do for RO slots or CREATE/MOVE/DELETE of a slot.
	 * Nothing to do for RO slots (which can't be dirtied and can't be made
	 * See comments below.
	 * writable) or CREATE/MOVE/DELETE of a slot.  See comments below.
	 */
	 */
	if ((change != KVM_MR_FLAGS_ONLY) || (new->flags & KVM_MEM_READONLY))
	if ((change != KVM_MR_FLAGS_ONLY) || (new->flags & KVM_MEM_READONLY))
		return;
		return;


	/*
	 * READONLY and non-flags changes were filtered out above, and the only
	 * other flag is LOG_DIRTY_PAGES, i.e. something is wrong if dirty
	 * logging isn't being toggled on or off.
	 */
	if (WARN_ON_ONCE(!((old->flags ^ new->flags) & KVM_MEM_LOG_DIRTY_PAGES)))
		return;

	/*
	/*
	 * Dirty logging tracks sptes in 4k granularity, meaning that large
	 * Dirty logging tracks sptes in 4k granularity, meaning that large
	 * sptes have to be split.  If live migration is successful, the guest
	 * sptes have to be split.  If live migration is successful, the guest
@@ -10784,8 +10792,7 @@ static void kvm_mmu_slot_apply_flags(struct kvm *kvm,
	 * MOVE/DELETE: The old mappings will already have been cleaned up by
	 * MOVE/DELETE: The old mappings will already have been cleaned up by
	 *		kvm_arch_flush_shadow_memslot()
	 *		kvm_arch_flush_shadow_memslot()
	 */
	 */
	if ((old->flags & KVM_MEM_LOG_DIRTY_PAGES) &&
	if (!(new->flags & KVM_MEM_LOG_DIRTY_PAGES))
	    !(new->flags & KVM_MEM_LOG_DIRTY_PAGES))
		kvm_mmu_zap_collapsible_sptes(kvm, new);
		kvm_mmu_zap_collapsible_sptes(kvm, new);


	/*
	/*