mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09:00
KVM: x86/mmu: Open code leaf invalidation from mmu_notifier
commit 50107e8b2a upstream.
The mmu_notifier path is a bit of a special snowflake, e.g. it zaps only a
single address space (because it's per-slot), and can't always yield.
Because of this, it calls kvm_tdp_mmu_zap_leafs() in ways that no one
else does.
Iterate manually over the leafs in response to an mmu_notifier
invalidation, instead of invoking kvm_tdp_mmu_zap_leafs(). Drop the
@can_yield param from kvm_tdp_mmu_zap_leafs() as its sole remaining
caller unconditionally passes "true".
Cc: stable@vger.kernel.org
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-Id: <20230916003916.2545000-2-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
733d7a5451
commit
cd41db6cb2
@@ -6093,7 +6093,7 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end)
|
|||||||
if (is_tdp_mmu_enabled(kvm)) {
|
if (is_tdp_mmu_enabled(kvm)) {
|
||||||
for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++)
|
for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++)
|
||||||
flush = kvm_tdp_mmu_zap_leafs(kvm, i, gfn_start,
|
flush = kvm_tdp_mmu_zap_leafs(kvm, i, gfn_start,
|
||||||
gfn_end, true, flush);
|
gfn_end, flush);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flush)
|
if (flush)
|
||||||
|
|||||||
@@ -956,12 +956,12 @@ static bool tdp_mmu_zap_leafs(struct kvm *kvm, struct kvm_mmu_page *root,
|
|||||||
* more SPTEs were zapped since the MMU lock was last acquired.
|
* more SPTEs were zapped since the MMU lock was last acquired.
|
||||||
*/
|
*/
|
||||||
bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, int as_id, gfn_t start, gfn_t end,
|
bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, int as_id, gfn_t start, gfn_t end,
|
||||||
bool can_yield, bool flush)
|
bool flush)
|
||||||
{
|
{
|
||||||
struct kvm_mmu_page *root;
|
struct kvm_mmu_page *root;
|
||||||
|
|
||||||
for_each_tdp_mmu_root_yield_safe(kvm, root, as_id)
|
for_each_tdp_mmu_root_yield_safe(kvm, root, as_id)
|
||||||
flush = tdp_mmu_zap_leafs(kvm, root, start, end, can_yield, flush);
|
flush = tdp_mmu_zap_leafs(kvm, root, start, end, true, flush);
|
||||||
|
|
||||||
return flush;
|
return flush;
|
||||||
}
|
}
|
||||||
@@ -1221,8 +1221,13 @@ int kvm_tdp_mmu_map(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
|
|||||||
bool kvm_tdp_mmu_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range,
|
bool kvm_tdp_mmu_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range,
|
||||||
bool flush)
|
bool flush)
|
||||||
{
|
{
|
||||||
return kvm_tdp_mmu_zap_leafs(kvm, range->slot->as_id, range->start,
|
struct kvm_mmu_page *root;
|
||||||
range->end, range->may_block, flush);
|
|
||||||
|
for_each_tdp_mmu_root_yield_safe(kvm, root, range->slot->as_id)
|
||||||
|
flush = tdp_mmu_zap_leafs(kvm, root, range->start, range->end,
|
||||||
|
range->may_block, flush);
|
||||||
|
|
||||||
|
return flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef bool (*tdp_handler_t)(struct kvm *kvm, struct tdp_iter *iter,
|
typedef bool (*tdp_handler_t)(struct kvm *kvm, struct tdp_iter *iter,
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ __must_check static inline bool kvm_tdp_mmu_get_root(struct kvm_mmu_page *root)
|
|||||||
void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root,
|
void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root,
|
||||||
bool shared);
|
bool shared);
|
||||||
|
|
||||||
bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, int as_id, gfn_t start,
|
bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, int as_id, gfn_t start, gfn_t end,
|
||||||
gfn_t end, bool can_yield, bool flush);
|
bool flush);
|
||||||
bool kvm_tdp_mmu_zap_sp(struct kvm *kvm, struct kvm_mmu_page *sp);
|
bool kvm_tdp_mmu_zap_sp(struct kvm *kvm, struct kvm_mmu_page *sp);
|
||||||
void kvm_tdp_mmu_zap_all(struct kvm *kvm);
|
void kvm_tdp_mmu_zap_all(struct kvm *kvm);
|
||||||
void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm);
|
void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm);
|
||||||
|
|||||||
Reference in New Issue
Block a user