[PATCH] KVM: x86/mmu: Bug the VM if KVM attempts to unsync an upper-level shadow page
Sean Christopherson <[email protected]>
| Newsgroups | org.kernel.vger.kvm,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> Signed-off-by: Sean Christopherson <[email protected]> --- 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