Skip to content

Commit 5cce890

Browse files
sean-jcgregkh
authored andcommitted
KVM: x86/mmu: Retry page faults that hit an invalid memslot
[ Upstream commit e0c3786 ] Retry page faults (re-enter the guest) that hit an invalid memslot instead of treating the memslot as not existing, i.e. handling the page fault as an MMIO access. When deleting a memslot, SPTEs aren't zapped and the TLBs aren't flushed until after the memslot has been marked invalid. Handling the invalid slot as MMIO means there's a small window where a page fault could replace a valid SPTE with an MMIO SPTE. The legacy MMU handles such a scenario cleanly, but the TDP MMU assumes such behavior is impossible (see the BUG() in __handle_changed_spte()). There's really no good reason why the legacy MMU should allow such a scenario, and closing this hole allows for additional cleanups. Fixes: 2f2fad0 ("kvm: x86/mmu: Add functions to handle changed TDP SPTEs") Cc: Ben Gardon <bgardon@google.com> Signed-off-by: Sean Christopherson <seanjc@google.com> Message-Id: <20210225204749.1512652-6-seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent cd6e679 commit 5cce890

1 file changed

Lines changed: 8 additions & 0 deletions

File tree

arch/x86/kvm/mmu/mmu.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3663,6 +3663,14 @@ static bool try_async_pf(struct kvm_vcpu *vcpu, bool prefault, gfn_t gfn,
36633663
struct kvm_memory_slot *slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn);
36643664
bool async;
36653665

3666+
/*
3667+
* Retry the page fault if the gfn hit a memslot that is being deleted
3668+
* or moved. This ensures any existing SPTEs for the old memslot will
3669+
* be zapped before KVM inserts a new MMIO SPTE for the gfn.
3670+
*/
3671+
if (slot && (slot->flags & KVM_MEMSLOT_INVALID))
3672+
return true;
3673+
36663674
/* Don't expose private memslots to L2. */
36673675
if (is_guest_mode(vcpu) && !kvm_is_visible_memslot(slot)) {
36683676
*pfn = KVM_PFN_NOSLOT;

0 commit comments

Comments
 (0)