KVM: MMU: remove mmu_seq verification on pte write path
PATCH 1/2 KVM: MMU: remove mmu_seq verification on pte write path
The mmu_seq verification can be removed since we get the pfn in the protection of mmu_lock
--- arch/x86/include/asm/kvm_host.h | 2 +- arch/x86/kvm/mmu.c | 16 +++++----------- arch/x86/kvm/paging_tmpl.h | 4 +--- 3 files changed, 7 insertions(+), 15 deletions(-)
arch/x86/include/asm/kvm_host.h +1 -1
@@ -258,7 +258,7 @@ struct kvm_mmu { struct kvm_mmu_page *sp);void (*invlpg)(struct kvm_vcpu *vcpu,gva_t gva);void (*update_pte)(struct kvm_vcpu *vcpu,struct kvm_mmu_page *sp, -u64 *spte,const void *pte,unsigned long mmu_seq); +u64 *spte,const void *pte);hpa_t root_hpa;int root_level;int shadow_root_level;
arch/x86/kvm/mmu.c +5 -11
@@ -1206,7 +1206,7 @@ static void nonpaging_invlpg(struct kvm_vcpu *vcpu, gva_t gva)static void nonpaging_update_pte (struct kvm_vcpu *vcpu,struct kvm_mmu_page *sp,u64 *spte, -const void *pte,unsigned long mmu_seq) +const void *pte) {WARN_ON (1 ); }
@@ -3163,9 +3163,8 @@ static void mmu_pte_write_zap_pte(struct kvm_vcpu *vcpu, }static void mmu_pte_write_new_pte (struct kvm_vcpu *vcpu, -struct kvm_mmu_page *sp, -u64 *spte, -const void *new,unsigned long mmu_seq) +struct kvm_mmu_page *sp,u64 *spte, +const void *new) {if (sp->role.level !=PT_PAGE_TABLE_LEVEL ) { ++vcpu->kvm->stat.mmu_pde_zapped;
@@ -3173,7 +3172,7 @@ static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu, } ++vcpu->kvm->stat.mmu_pte_updated; - vcpu->arch.mmu.update_pte (vcpu, sp, spte, new, mmu_seq); + vcpu->arch.mmu.update_pte (vcpu, sp, spte, new); }static bool need_remote_flush (u64 old,u64 new)
@@ -3229,7 +3228,6 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,struct kvm_mmu_page *sp;struct hlist_node *node;LIST_HEAD (invalid_list); -unsigned long mmu_seq;u64 entry, gentry, *spte;unsigned pte_size, page_offset, misaligned, quadrant, offset;int level, npte, invlpg_counter, r, flooded =0 ;
@@ -3271,9 +3269,6 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,break ; } - mmu_seq = vcpu->kvm->mmu_notifier_seq; -smp_rmb (); -spin_lock (&vcpu->kvm->mmu_lock);if (atomic_read (&vcpu->kvm->arch.invlpg_counter) != invlpg_counter) gentry =0 ;
@@ -3345,8 +3340,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,if (gentry && !((sp->role.word ^ vcpu->arch.mmu.base_role.word) & mask.word)) -mmu_pte_write_new_pte (vcpu, sp, spte, &gentry, - mmu_seq); +mmu_pte_write_new_pte (vcpu, sp, spte, &gentry);if (!remote_flush &&need_remote_flush (entry, *spte)) remote_flush = true; ++spte;
arch/x86/kvm/paging_tmpl.h +1 -3
@@ -325,7 +325,7 @@ no_present: }static void FNAME (update_pte )(struct kvm_vcpu *vcpu,struct kvm_mmu_page *sp, -u64 *spte,const void *pte,unsigned long mmu_seq) +u64 *spte,const void *pte) {pt_element_t gpte;unsigned pte_access;
@@ -342,8 +342,6 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,kvm_release_pfn_clean (pfn);return ; } -if (mmu_notifier_retry (vcpu, mmu_seq)) -return ;/* * we call mmu_set_spte() with host_writable = true because that
Signature · 1 line
1.7.4
PATCH 2/2 KVM: MMU: optimize pte write path if don't have protected sp
Simplely return from kvm_mmu_pte_write path if no shadow page is write-protected, than we can avoid to walk all shadow pages and hold mmu-lock
--- arch/x86/kvm/mmu.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
arch/x86/kvm/mmu.c +8 -0
@@ -3219,6 +3219,11 @@ static void kvm_mmu_access_page(struct kvm_vcpu *vcpu, gfn_t gfn)set_bit (PT_ACCESSED_SHIFT , (unsigned long *)spte); } +static bool need_track_pte_changed (struct kvm_vcpu *vcpu) +{ +return !tdp_enabled ||mmu_is_nested (vcpu); +} +void kvm_mmu_pte_write (struct kvm_vcpu *vcpu,gpa_t gpa,const u8 *new,int bytes,bool guest_initiated)
@@ -3233,6 +3238,9 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,int level, npte, invlpg_counter, r, flooded =0 ;bool remote_flush, local_flush, zap_page; +if (!need_track_pte_changed (vcpu)) +return ; + zap_page = remote_flush = local_flush = false; offset =offset_in_page (gpa);
Signature · 1 line
1.7.4
Re: [PATCH 2/2] KVM: MMU: optimize pte write path if don't have protected sp
Quoted 14 lines · Xiao Guangrong
Simplely return from
kvm_mmu_pte_writepath if no shadow page is write-protected, than we can avoid to walk all shadow pages and hold mmu-lockSigned-off-by Xiao Guangrong<[email protected]>--- arch/x86/kvm/mmu.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)arch/x86/kvm/mmu.c +0
-0
arch/x86/kvm/mmu.c static void kvm_mmu_access_page(struct kvm_vcpu *vcpu, gfn_t gfn) · line 3226
Quoted 8 lines
arch/x86/kvm/mmu.c +5
-0@@ -3219,6 +3219,11 @@ static void kvm_mmu_access_page(struct kvm_vcpu *vcpu, gfn_t gfn)set_bit (PT_ACCESSED_SHIFT , (unsigned long *)spte); } +static bool need_track_pte_changed (struct kvm_vcpu *vcpu) +{ +return !tdp_enabled ||mmu_is_nested (vcpu); +} +
What happens if this vcpu is nested but another vcpu is not?
Or if we have some indirect pages, but currently we're in non-nested mode?
Suggest instead to keep track of the number of indirect pages across the guest. If it's zero, we can exit early.
Quoted 13 lines
arch/x86/kvm/mmu.c +3
-0void kvm_mmu_pte_write (struct kvm_vcpu *vcpu,gpa_t gpa,const u8 *new,int bytes,bool guest_initiated)@@ -3233,6 +3238,9 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,int level, npte, invlpg_counter, r, flooded =0 ;bool remote_flush, local_flush, zap_page; +if (!need_track_pte_changed (vcpu)) +return ; + zap_page = remote_flush = local_flush = false; offset =offset_in_page (gpa);
Signature · 1 line
error compiling committee.c: too many arguments to function
Avi Kivity
AppliedQuoted 2 lines · Xiao Guangrong
The
mmu_seqverification can be removed since we get the pfn in the protection ofmmu_lock
Applied, thanks.
Signature · 1 line
error compiling committee.c: too many arguments to function