[PATCH] KVM: x86/mmu: Bug the VM if KVM attempts to unsync an upper-level shadow page

From: Sean Christopherson

Date: Thu Aug 06 2026 - 15:20:09 EST


Bug the VM and skip marking a shadow page unsync if KVM attempts to unsync
an upper-level shadow page, as marking an upper-level SP unsync is all but
guaranteed to be far worse than terminating the VM. E.g. sync_spte()
(rightly) assumes SPTEs in the SP are leaf SPTEs and so calls drop_spte()
instead of drop_parent_pte(), which can effectively crash the host via
when running with CONFIG_BUG_ON_DATA_CORRUPTION=y due to there not being an
rmap entry for the SPTE.

Simply not marking the SP unsync, i.e. letting the VM continue on, is
equally dangerous for the guest as it means KVM's shadow MMU is using stale
information, e.g. could unintentionally corrupt the guest.

Cc: Jinu Kim <kimjw04271234@xxxxxxxxx>
Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
---
arch/x86/kvm/mmu/mmu.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 6c13da942bfc..d9ad158ff7a2 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -2990,6 +2990,9 @@ int mmu_try_to_unsync_pages(struct kvm *kvm, const struct kvm_memory_slot *slot,
if (prefetch)
return -EEXIST;

+ if (KVM_BUG_ON(sp->role.level != PG_LEVEL_4K, kvm))
+ continue;
+
/*
* TDP MMU page faults require an additional spinlock as they
* run with mmu_lock held for read, not write, and the unsync
@@ -3013,7 +3016,6 @@ int mmu_try_to_unsync_pages(struct kvm *kvm, const struct kvm_memory_slot *slot,
continue;
}

- WARN_ON_ONCE(sp->role.level != PG_LEVEL_4K);
kvm_unsync_page(kvm, sp);
}
if (locked)

base-commit: a204badd8432f93b7e862e7dac6db0fe3d65f370
--
2.55.0.679.g6767b8d81c-goog