mirror of
https://github.com/torvalds/linux.git
synced 2026-07-30 03:01:41 +02:00
KVM: x86/mmu: Plumb "sp" _pointer_ into the TDP MMU's handle_changed_spte()
Plumb the "sp" pointer into handle_changed_spte() to allow checking of is_mirror_sp(sp) in handle_changed_spte(). This will allow consolidating all S-EPT updates into a single kvm_x86_ops hook. [Yan: Remove unused "as_id" param in tdp_mmu_set_spte() ] Signed-off-by: Yan Zhao <yan.y.zhao@intel.com> Link: https://patch.msgid.link/20260509075622.4258-1-yan.y.zhao@intel.com Signed-off-by: Sean Christopherson <seanjc@google.com>
This commit is contained in:
parent
c1d3af136f
commit
c1ec7f368d
|
|
@ -320,9 +320,9 @@ void kvm_tdp_mmu_alloc_root(struct kvm_vcpu *vcpu, bool mirror)
|
|||
}
|
||||
}
|
||||
|
||||
static void handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn,
|
||||
u64 old_spte, u64 new_spte, int level,
|
||||
bool shared);
|
||||
static void handle_changed_spte(struct kvm *kvm, struct kvm_mmu_page *sp,
|
||||
gfn_t gfn, u64 old_spte, u64 new_spte,
|
||||
int level, bool shared);
|
||||
|
||||
static void tdp_account_mmu_page(struct kvm *kvm, struct kvm_mmu_page *sp)
|
||||
{
|
||||
|
|
@ -471,8 +471,7 @@ static void handle_removed_pt(struct kvm *kvm, tdp_ptep_t pt, bool shared)
|
|||
old_spte = kvm_tdp_mmu_write_spte(sptep, old_spte,
|
||||
FROZEN_SPTE, level);
|
||||
}
|
||||
handle_changed_spte(kvm, kvm_mmu_page_as_id(sp), gfn,
|
||||
old_spte, FROZEN_SPTE, level, shared);
|
||||
handle_changed_spte(kvm, sp, gfn, old_spte, FROZEN_SPTE, level, shared);
|
||||
|
||||
if (is_mirror_sp(sp)) {
|
||||
KVM_BUG_ON(shared, kvm);
|
||||
|
|
@ -498,7 +497,7 @@ static void handle_removed_pt(struct kvm *kvm, tdp_ptep_t pt, bool shared)
|
|||
/**
|
||||
* handle_changed_spte - handle bookkeeping associated with an SPTE change
|
||||
* @kvm: kvm instance
|
||||
* @as_id: the address space of the paging structure the SPTE was a part of
|
||||
* @sp: the page table in which the SPTE resides
|
||||
* @gfn: the base GFN that was mapped by the SPTE
|
||||
* @old_spte: The value of the SPTE before the change
|
||||
* @new_spte: The value of the SPTE after the change
|
||||
|
|
@ -511,15 +510,16 @@ static void handle_removed_pt(struct kvm *kvm, tdp_ptep_t pt, bool shared)
|
|||
* dirty logging updates are handled in common code, not here (see make_spte()
|
||||
* and fast_pf_fix_direct_spte()).
|
||||
*/
|
||||
static void handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn,
|
||||
u64 old_spte, u64 new_spte, int level,
|
||||
bool shared)
|
||||
static void handle_changed_spte(struct kvm *kvm, struct kvm_mmu_page *sp,
|
||||
gfn_t gfn, u64 old_spte, u64 new_spte,
|
||||
int level, bool shared)
|
||||
{
|
||||
bool was_present = is_shadow_present_pte(old_spte);
|
||||
bool is_present = is_shadow_present_pte(new_spte);
|
||||
bool was_leaf = was_present && is_last_spte(old_spte, level);
|
||||
bool is_leaf = is_present && is_last_spte(new_spte, level);
|
||||
bool pfn_changed = spte_to_pfn(old_spte) != spte_to_pfn(new_spte);
|
||||
int as_id = kvm_mmu_page_as_id(sp);
|
||||
|
||||
WARN_ON_ONCE(level > PT64_ROOT_MAX_LEVEL);
|
||||
WARN_ON_ONCE(level < PG_LEVEL_4K);
|
||||
|
|
@ -668,6 +668,7 @@ static inline int __must_check tdp_mmu_set_spte_atomic(struct kvm *kvm,
|
|||
struct tdp_iter *iter,
|
||||
u64 new_spte)
|
||||
{
|
||||
struct kvm_mmu_page *sp = sptep_to_sp(rcu_dereference(iter->sptep));
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held_read(&kvm->mmu_lock);
|
||||
|
|
@ -676,7 +677,7 @@ static inline int __must_check tdp_mmu_set_spte_atomic(struct kvm *kvm,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
handle_changed_spte(kvm, iter->as_id, iter->gfn, iter->old_spte,
|
||||
handle_changed_spte(kvm, sp, iter->gfn, iter->old_spte,
|
||||
new_spte, iter->level, true);
|
||||
|
||||
return 0;
|
||||
|
|
@ -685,7 +686,6 @@ static inline int __must_check tdp_mmu_set_spte_atomic(struct kvm *kvm,
|
|||
/*
|
||||
* tdp_mmu_set_spte - Set a TDP MMU SPTE and handle the associated bookkeeping
|
||||
* @kvm: KVM instance
|
||||
* @as_id: Address space ID, i.e. regular vs. SMM
|
||||
* @sptep: Pointer to the SPTE
|
||||
* @old_spte: The current value of the SPTE
|
||||
* @new_spte: The new value that will be set for the SPTE
|
||||
|
|
@ -695,9 +695,11 @@ static inline int __must_check tdp_mmu_set_spte_atomic(struct kvm *kvm,
|
|||
* Returns the old SPTE value, which _may_ be different than @old_spte if the
|
||||
* SPTE had voldatile bits.
|
||||
*/
|
||||
static u64 tdp_mmu_set_spte(struct kvm *kvm, int as_id, tdp_ptep_t sptep,
|
||||
u64 old_spte, u64 new_spte, gfn_t gfn, int level)
|
||||
static u64 tdp_mmu_set_spte(struct kvm *kvm, tdp_ptep_t sptep, u64 old_spte,
|
||||
u64 new_spte, gfn_t gfn, int level)
|
||||
{
|
||||
struct kvm_mmu_page *sp = sptep_to_sp(rcu_dereference(sptep));
|
||||
|
||||
lockdep_assert_held_write(&kvm->mmu_lock);
|
||||
|
||||
/*
|
||||
|
|
@ -711,7 +713,7 @@ static u64 tdp_mmu_set_spte(struct kvm *kvm, int as_id, tdp_ptep_t sptep,
|
|||
|
||||
old_spte = kvm_tdp_mmu_write_spte(sptep, old_spte, new_spte, level);
|
||||
|
||||
handle_changed_spte(kvm, as_id, gfn, old_spte, new_spte, level, false);
|
||||
handle_changed_spte(kvm, sp, gfn, old_spte, new_spte, level, false);
|
||||
|
||||
/*
|
||||
* Users that do non-atomic setting of PTEs don't operate on mirror
|
||||
|
|
@ -729,9 +731,8 @@ static inline void tdp_mmu_iter_set_spte(struct kvm *kvm, struct tdp_iter *iter,
|
|||
u64 new_spte)
|
||||
{
|
||||
WARN_ON_ONCE(iter->yielded);
|
||||
iter->old_spte = tdp_mmu_set_spte(kvm, iter->as_id, iter->sptep,
|
||||
iter->old_spte, new_spte,
|
||||
iter->gfn, iter->level);
|
||||
iter->old_spte = tdp_mmu_set_spte(kvm, iter->sptep, iter->old_spte,
|
||||
new_spte, iter->gfn, iter->level);
|
||||
}
|
||||
|
||||
#define tdp_root_for_each_pte(_iter, _kvm, _root, _start, _end) \
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user