Skip to content

Commit

Permalink
KVM: x86/mmu: Ensure TLBs are flushed for TDP MMU during NX zapping
Browse files Browse the repository at this point in the history
[ Upstream commit 048f498 ]

Honor the "flush needed" return from kvm_tdp_mmu_zap_gfn_range(), which
does the flush itself if and only if it yields (which it will never do in
this particular scenario), and otherwise expects the caller to do the
flush.  If pages are zapped from the TDP MMU but not the legacy MMU, then
no flush will occur.

Fixes: 29cf0f5 ("kvm: x86/mmu: NX largepage recovery for TDP MMU")
Cc: stable@vger.kernel.org
Cc: Ben Gardon <bgardon@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-Id: <20210325200119.1359384-3-seanjc@google.com>
Reviewed-by: Ben Gardon <bgardon@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
sean-jc authored and gregkh committed Apr 14, 2021
1 parent a71471e commit e924752
Showing 1 changed file with 8 additions and 5 deletions.
13 changes: 8 additions & 5 deletions arch/x86/kvm/mmu/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -5985,6 +5985,8 @@ static void kvm_recover_nx_lpages(struct kvm *kvm)
struct kvm_mmu_page *sp;
unsigned int ratio;
LIST_HEAD(invalid_list);
bool flush = false;
gfn_t gfn_end;
ulong to_zap;

rcu_idx = srcu_read_lock(&kvm->srcu);
Expand All @@ -6006,19 +6008,20 @@ static void kvm_recover_nx_lpages(struct kvm *kvm)
lpage_disallowed_link);
WARN_ON_ONCE(!sp->lpage_disallowed);
if (sp->tdp_mmu_page)
kvm_tdp_mmu_zap_gfn_range(kvm, sp->gfn,
sp->gfn + KVM_PAGES_PER_HPAGE(sp->role.level));
else {
gfn_end = sp->gfn + KVM_PAGES_PER_HPAGE(sp->role.level);
flush = kvm_tdp_mmu_zap_gfn_range(kvm, sp->gfn, gfn_end);
} else {
kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list);
WARN_ON_ONCE(sp->lpage_disallowed);
}

if (need_resched() || spin_needbreak(&kvm->mmu_lock)) {
kvm_mmu_commit_zap_page(kvm, &invalid_list);
kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, flush);
cond_resched_lock(&kvm->mmu_lock);
flush = false;
}
}
kvm_mmu_commit_zap_page(kvm, &invalid_list);
kvm_mmu_remote_flush_or_zap(kvm, &invalid_list, flush);

spin_unlock(&kvm->mmu_lock);
srcu_read_unlock(&kvm->srcu, rcu_idx);
Expand Down

0 comments on commit e924752

Please sign in to comment.