lkml.org 
[lkml]   [2021]   [May]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 354/530] KVM: x86/mmu: Retry page faults that hit an invalid memslot
    Date
    From: Sean Christopherson <seanjc@google.com>

    [ Upstream commit e0c378684b6545ad2d4403bb701d0ac4932b4e95 ]

    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: 2f2fad0897cb ("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>
    ---
    arch/x86/kvm/mmu/mmu.c | 8 ++++++++
    1 file changed, 8 insertions(+)

    diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
    index 2d37068b7cd5..2f2576fd343e 100644
    --- a/arch/x86/kvm/mmu/mmu.c
    +++ b/arch/x86/kvm/mmu/mmu.c
    @@ -3663,6 +3663,14 @@ static bool try_async_pf(struct kvm_vcpu *vcpu, bool prefault, gfn_t gfn,
    struct kvm_memory_slot *slot = kvm_vcpu_gfn_to_memslot(vcpu, gfn);
    bool async;

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


    \
     
     \ /
      Last update: 2021-05-12 19:01    [W:4.262 / U:0.080 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site