KVM: MMU: rename 'no_apf' to 'prefault'
PATCH v4 1/3 KVM: MMU: rename 'no_apf' to 'prefault'
It's the speculative path if 'no_apf = 1' and we will specially handle this speculative path in the later patch, so 'prefault' is better to fit the sense
--- arch/x86/include/asm/kvm_host.h | 3 ++- arch/x86/kvm/mmu.c | 18 +++++++++--------- arch/x86/kvm/paging_tmpl.h | 4 ++-- 3 files changed, 13 insertions(+), 12 deletions(-)
arch/x86/include/asm/kvm_host.h +2 -1
@@ -241,7 +241,8 @@ struct kvm_mmu {void (*new_cr3)(struct kvm_vcpu *vcpu);void (*set_cr3)(struct kvm_vcpu *vcpu,unsigned long root);unsigned long (*get_cr3)(struct kvm_vcpu *vcpu); -int (*page_fault)(struct kvm_vcpu *vcpu,gva_t gva,u32 err,bool no_apf); +int (*page_fault)(struct kvm_vcpu *vcpu,gva_t gva,u32 err, +bool prefault);void (*inject_page_fault)(struct kvm_vcpu *vcpu);void (*free)(struct kvm_vcpu *vcpu); gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t gva, u32 access,
arch/x86/kvm/mmu.c +9 -9
@@ -2284,11 +2284,11 @@ static int kvm_handle_bad_page(struct kvm *kvm, gfn_t gfn, pfn_t pfn)return 1 ; } -static bool try_async_pf (struct kvm_vcpu *vcpu,bool no_apf,gfn_t gfn, +static bool try_async_pf (struct kvm_vcpu *vcpu,bool prefault,gfn_t gfn,gva_t gva,pfn_t *pfn,bool write,bool *writable);static int nonpaging_map (struct kvm_vcpu *vcpu,gva_t v,int write,gfn_t gfn, -bool no_apf) +bool prefault) {int r;int level;
@@ -2310,7 +2310,7 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn, mmu_seq = vcpu->kvm->mmu_notifier_seq;smp_rmb (); -if (try_async_pf (vcpu, no_apf, gfn, v, &pfn, write, &map_writable)) +if (try_async_pf (vcpu, prefault, gfn, v, &pfn, write, &map_writable))return 0 ;/* mmio */
@@ -2583,7 +2583,7 @@ static gpa_t nonpaging_gva_to_gpa_nested(struct kvm_vcpu *vcpu, gva_t vaddr, }static int nonpaging_page_fault (struct kvm_vcpu *vcpu,gva_t gva, -u32 error_code,bool no_apf) +u32 error_code,bool prefault) {gfn_t gfn;int r;
@@ -2599,7 +2599,7 @@ static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva, gfn = gva >>PAGE_SHIFT ;return nonpaging_map (vcpu, gva &PAGE_MASK , - error_code &PFERR_WRITE_MASK , gfn, no_apf); + error_code &PFERR_WRITE_MASK , gfn, prefault); }static int kvm_arch_setup_async_pf (struct kvm_vcpu *vcpu,gva_t gva,gfn_t gfn)
@@ -2621,7 +2621,7 @@ static bool can_do_async_pf(struct kvm_vcpu *vcpu)return kvm_x86_ops->interrupt_allowed (vcpu); } -static bool try_async_pf (struct kvm_vcpu *vcpu,bool no_apf,gfn_t gfn, +static bool try_async_pf (struct kvm_vcpu *vcpu,bool prefault,gfn_t gfn,gva_t gva,pfn_t *pfn,bool write,bool *writable) {bool async;
@@ -2633,7 +2633,7 @@ static bool try_async_pf(struct kvm_vcpu *vcpu, bool no_apf, gfn_t gfn,put_page (pfn_to_page (*pfn)); -if (!no_apf &&can_do_async_pf (vcpu)) { +if (!prefault &&can_do_async_pf (vcpu)) {trace_kvm_try_async_get_page (gva, gfn);if (kvm_find_async_pf_gfn (vcpu, gfn)) {trace_kvm_async_pf_doublefault (gva, gfn);
@@ -2649,7 +2649,7 @@ static bool try_async_pf(struct kvm_vcpu *vcpu, bool no_apf, gfn_t gfn, }static int tdp_page_fault (struct kvm_vcpu *vcpu,gva_t gpa,u32 error_code, -bool no_apf) +bool prefault) {pfn_t pfn;int r;
@@ -2673,7 +2673,7 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa, u32 error_code, mmu_seq = vcpu->kvm->mmu_notifier_seq;smp_rmb (); -if (try_async_pf (vcpu, no_apf, gfn, gpa, &pfn, write, &map_writable)) +if (try_async_pf (vcpu, prefault, gfn, gpa, &pfn, write, &map_writable))return 0 ;/* mmio */
arch/x86/kvm/paging_tmpl.h +2 -2
@@ -539,7 +539,7 @@ out_gpte_changed:* a negative value on error. */ static int FNAME (page_fault )(struct kvm_vcpu *vcpu,gva_t addr,u32 error_code, -bool no_apf) +bool prefault) {int write_fault = error_code &PFERR_WRITE_MASK ;int user_fault = error_code &PFERR_USER_MASK ;
@@ -581,7 +581,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code, mmu_seq = vcpu->kvm->mmu_notifier_seq;smp_rmb (); -if (try_async_pf (vcpu, no_apf, walker.gfn, addr, &pfn, write_fault, +if (try_async_pf (vcpu, prefault, walker.gfn, addr, &pfn, write_fault, &map_writable))return 0 ;
Signature · 1 line
1.7.0.4
PATCH v4 2/3 KVM: MMU: fix accessed bit set on prefault path
Retry #PF is the speculative path, so don't set the accessed bit
--- arch/x86/kvm/mmu.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-)
arch/x86/kvm/mmu.c +6 -4
@@ -2214,7 +2214,8 @@ static void direct_pte_prefetch(struct kvm_vcpu *vcpu, u64 *sptep) }static int __direct_map (struct kvm_vcpu *vcpu,gpa_t v,int write, -int map_writable,int level,gfn_t gfn,pfn_t pfn) +int map_writable,int level,gfn_t gfn,pfn_t pfn, +bool prefault) {struct kvm_shadow_walk_iterator iterator;struct kvm_mmu_page *sp;
@@ -2229,7 +2230,7 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, pte_access &= ~ACC_WRITE_MASK ;mmu_set_spte (vcpu, iterator.sptep,ACC_ALL , pte_access,0 , write,1 , &pt_write, - level, gfn, pfn, false, map_writable); + level, gfn, pfn, prefault, map_writable);direct_pte_prefetch (vcpu, iterator.sptep); ++vcpu->stat.pf_fixed;break ;
@@ -2321,7 +2322,8 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn,if (mmu_notifier_retry (vcpu, mmu_seq)) goto out_unlock;kvm_mmu_free_some_pages (vcpu); - r =__direct_map (vcpu, v, write, map_writable, level, gfn, pfn); + r =__direct_map (vcpu, v, write, map_writable, level, gfn, pfn, + prefault);spin_unlock (&vcpu->kvm->mmu_lock);
@@ -2684,7 +2686,7 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa, u32 error_code, goto out_unlock;kvm_mmu_free_some_pages (vcpu); r =__direct_map (vcpu, gpa, write, map_writable, - level, gfn, pfn); + level, gfn, pfn, prefault);spin_unlock (&vcpu->kvm->mmu_lock);return r;
Signature · 1 line
1.7.0.4
PATCH v4 3/3 KVM: MMU: retry #PF for softmmu
In reply to Xiao GuangrongRetry #PF for softmmu only when the current vcpu has the same cr3 as the time when #PF occurs
Changelog:
Just compare cr3 value since It's harmless to instantiate an spte for an unused translation from Marcelo's comment
arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/mmu.c | 2 ++ arch/x86/kvm/paging_tmpl.h | 34 +++++++++++++++++++++++----------- arch/x86/kvm/x86.c | 6 +++++- 4 files changed, 31 insertions(+), 12 deletions(-)
arch/x86/include/asm/kvm_host.h +1 -0
@@ -602,6 +602,7 @@ struct kvm_x86_ops {struct kvm_arch_async_pf {u32 token;gfn_t gfn; +unsigned long cr3;bool direct_map; };
arch/x86/kvm/mmu.c +2 -0
@@ -2607,9 +2607,11 @@ static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva,static int kvm_arch_setup_async_pf (struct kvm_vcpu *vcpu,gva_t gva,gfn_t gfn) {struct kvm_arch_async_pf arch; + arch.token = (vcpu->arch.apf.id++ <<12 ) | vcpu->vcpu_id; arch.gfn = gfn; arch.direct_map = vcpu->arch.mmu.direct_map; + arch.cr3 = vcpu->arch.mmu.get_cr3 (vcpu);return kvm_setup_async_pf (vcpu, gva, gfn, &arch); }
arch/x86/kvm/paging_tmpl.h +23 -11
@@ -116,7 +116,7 @@ static unsigned FNAME(gpte_access)(struct kvm_vcpu *vcpu, pt_element_t gpte)*/ static int FNAME (walk_addr_generic )(struct guest_walker *walker,struct kvm_vcpu *vcpu,struct kvm_mmu *mmu, -gva_t addr,u32 access) +gva_t addr,u32 access,bool prefault) {pt_element_t pte;gfn_t table_gfn;
@@ -194,6 +194,13 @@ walk:#endif if (!eperm && !rsvd_fault && !(pte &PT_ACCESSED_MASK )) { +/* +* Don't set gpte accessed bit if it's on +* speculative path. +*/ +if (prefault) + goto error; +trace_kvm_mmu_set_accessed_bit (table_gfn, index,sizeof (pte)); if (FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn,
@@ -287,10 +294,11 @@ error: }static int FNAME (walk_addr )(struct guest_walker *walker, -struct kvm_vcpu *vcpu,gva_t addr,u32 access) +struct kvm_vcpu *vcpu,gva_t addr, +u32 access,bool prefault) {return FNAME (walk_addr_generic)(walker, vcpu, &vcpu->arch.mmu, addr, - access); + access, prefault); } static int FNAME(walk_addr_nested)(struct guest_walker *walker,
@@ -298,7 +306,7 @@ static int FNAME(walk_addr_nested)(struct guest_walker *walker, u32 access) {return FNAME (walk_addr_generic)(walker, vcpu, &vcpu->arch.nested_mmu, - addr, access); + addr, access, false); } static bool FNAME(prefetch_invalid_gpte)(struct kvm_vcpu *vcpu,
@@ -438,7 +446,8 @@ static void FNAME(pte_prefetch)(struct kvm_vcpu *vcpu, struct guest_walker *gw,static u64 *FNAME (fetch )(struct kvm_vcpu *vcpu,gva_t addr,struct guest_walker *gw,int user_fault,int write_fault,int hlevel, -int *ptwrite,pfn_t pfn,bool map_writable) +int *ptwrite,pfn_t pfn,bool map_writable, +bool prefault) {unsigned access = gw->pt_access;struct kvm_mmu_page *sp =NULL ;
@@ -512,7 +521,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,mmu_set_spte (vcpu, it.sptep, access, gw->pte_access & access, user_fault, write_fault, dirty, ptwrite, it.level, - gw->gfn, pfn, false, map_writable); + gw->gfn, pfn, prefault, map_writable);FNAME (pte_prefetch)(vcpu, gw, it.sptep);return it.sptep;
@@ -561,15 +570,18 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code,/* * Look up the guest pte for the faulting address. */ - r =FNAME (walk_addr)(&walker, vcpu, addr, error_code); + r =FNAME (walk_addr)(&walker, vcpu, addr, error_code, prefault);/* * The page is not mapped by the guest. Let the guest handle it. */ if (!r) {pgprintk ("%s: guest page fault\n" , __func__); -inject_page_fault (vcpu); - vcpu->arch.last_pt_write_count =0 ;/* reset fork detector */ +if (!prefault) { +inject_page_fault (vcpu); +/* reset fork detector */ + vcpu->arch.last_pt_write_count =0 ; + }return 0 ; }
@@ -599,7 +611,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code,trace_kvm_mmu_audit (vcpu,AUDIT_PRE_PAGE_FAULT );kvm_mmu_free_some_pages (vcpu); sptep =FNAME (fetch)(vcpu, addr, &walker, user_fault, write_fault, - level, &write_pt, pfn, map_writable); + level, &write_pt, pfn, map_writable, prefault); (void )sptep;pgprintk ("%s: shadow pte %p %llx ptwrite %d\n" , __func__, sptep, *sptep, write_pt);
@@ -685,7 +697,7 @@ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr, u32 access,gpa_t gpa =UNMAPPED_GVA ;int r; - r =FNAME (walk_addr)(&walker, vcpu, vaddr, access); + r =FNAME (walk_addr)(&walker, vcpu, vaddr, access, false);if (r) { gpa =gfn_to_gpa (walker.gfn);
arch/x86/kvm/x86.c +5 -1
@@ -6183,7 +6183,7 @@ void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu, struct kvm_async_pf *work) {int r; -if (!vcpu->arch.mmu.direct_map || !work->arch.direct_map || +if ((vcpu->arch.mmu.direct_map != work->arch.direct_map) ||is_error_page (work->page))return ;
@@ -6191,6 +6191,10 @@ void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu, struct kvm_async_pf *work)if (unlikely (r))return ; +if (!vcpu->arch.mmu.direct_map && + work->arch.cr3 != vcpu->arch.mmu.get_cr3 (vcpu)) +return ; + vcpu->arch.mmu.page_fault (vcpu, work->gva,0 , true); }
Signature · 1 line
1.7.0.4
Re: [PATCH v4 3/3] KVM: MMU: retry #PF for softmmu
Quoted 7 lines · Xiao Guangrong
Retry #PF for softmmu only when the current vcpu has the same cr3 as the time when #PF occurs
Changelog:
Just compare cr3 value since It's harmless to instantiate an spte for an unused translation from Marcelo's comment
It's not harmless. We could be in a different process, so we have to re-fetch the gpte. Or we could have switched from one nested guest to another.
Quoted 31 lines
arch/x86/kvm/mmu.c +2
-0@@ -2607,9 +2607,11 @@ static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva,static int kvm_arch_setup_async_pf (struct kvm_vcpu *vcpu,gva_t gva,gfn_t gfn) {struct kvm_arch_async_pf arch; + arch.token = (vcpu->arch.apf.id++<<12 ) | vcpu->vcpu_id; arch.gfn = gfn; arch.direct_map = vcpu->arch.mmu.direct_map; + arch.cr3 = vcpu->arch.mmu.get_cr3 (vcpu);return kvm_setup_async_pf (vcpu, gva, gfn,&arch); }arch/x86/kvm/paging_tmpl.h +1
-1@@ -116,7 +116,7 @@ static unsigned FNAME(gpte_access)(struct kvm_vcpu *vcpu, pt_element_t gpte)*/ static int FNAME (walk_addr_generic )(struct guest_walker *walker,struct kvm_vcpu *vcpu,struct kvm_mmu *mmu, -gva_t addr,u32 access) +gva_t addr,u32 access,bool prefault) {pt_element_t pte;gfn_t table_gfn;
arch/x86/kvm/paging_tmpl.h walk: · line 202
Quoted 9 lines
arch/x86/kvm/paging_tmpl.h +6
-0@@ -194,6 +194,13 @@ walk:#endif if (!eperm&& !rsvd_fault&& !(pte&PT_ACCESSED_MASK )) { +/* +* Don't set gpte accessed bit if it's on +* speculative path. +*/ +if (prefault) + goto error;
It's actually legal to set the accessed bit on speculative access.
Signature · 1 line
error compiling committee.c: too many arguments to function
Re: [PATCH v4 3/3] KVM: MMU: retry #PF for softmmu
Hi Avi,
Quoted 11 lines · Avi Kivity
Quoted 9 lines · Xiao Guangrong
Retry #PF for softmmu only when the current vcpu has the same cr3 as the time
when #PF occursChangelog:
Just compare cr3 value since It's harmless to instantiate an spte
for an
unused translation from Marcelo's comment
Quoted 4 lines
It's not harmless. We could be in a different process, so we have to re-fetch the gpte. Or we could have switched from one nested guest to another.
But it does this in this patch: re-walk guest page table and fixes guest's shadow page (not use any info when apf is occurred)
Quoted 10 lines
arch/x86/kvm/paging_tmpl.h walk: · line 202
Quoted 7 lines
if (!eperm&& !rsvd_fault&& !(pte& PT_ACCESSED_MASK)) {arch/x86/kvm/paging_tmpl.h +6
-0+/* +* Don't set gpte accessed bit if it's on +* speculative path. +*/ +if (prefault) + goto error;It's actually legal to set the accessed bit on speculative access.
Oh, you are right, thanks for your reminder.
Re: [PATCH v4 3/3] KVM: MMU: retry #PF for softmmu
Quoted 14 lines · Xiao Guangrong
Hi Avi,
Quoted 11 lines · Avi Kivity
Quoted 9 lines · Xiao Guangrong
Retry #PF for softmmu only when the current vcpu has the same cr3 as the time
when #PF occursChangelog:
Just compare cr3 value since It's harmless to instantiate an spte
for an
unused translation from Marcelo's comment
Quoted 7 lines
Quoted 4 lines
It's not harmless. We could be in a different process, so we have to re-fetch the gpte. Or we could have switched from one nested guest to another.
But it does this in this patch: re-walk guest page table and fixes guest's shadow page (not use any info when apf is occurred)
Right. Please resend without the walk_addr() changes. While they're correct, I'd like to keep that part simpler.
Signature · 1 line
error compiling committee.c: too many arguments to function
PATCH v4 3/3 KVM: MMU: retry #PF for softmmu
In reply to Xiao GuangrongRetry #PF for softmmu only when the current vcpu has the same cr3 as the time when #PF occurs
Changelog:
Just compare cr3 value since It's harmless to instantiate an spte for an unused translation from Marcelo's comment
--- arch/x86/include/asm/kvm_host.h | 1 + arch/x86/kvm/mmu.c | 2 ++ arch/x86/kvm/paging_tmpl.h | 34 +++++++++++++++++++++++----------- arch/x86/kvm/x86.c | 6 +++++- 4 files changed, 31 insertions(+), 12 deletions(-)
arch/x86/include/asm/kvm_host.h +1 -0
@@ -602,6 +602,7 @@ struct kvm_x86_ops {struct kvm_arch_async_pf {u32 token;gfn_t gfn; +unsigned long cr3;bool direct_map; };
arch/x86/kvm/mmu.c +2 -0
@@ -2607,9 +2607,11 @@ static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva,static int kvm_arch_setup_async_pf (struct kvm_vcpu *vcpu,gva_t gva,gfn_t gfn) {struct kvm_arch_async_pf arch; + arch.token = (vcpu->arch.apf.id++ <<12 ) | vcpu->vcpu_id; arch.gfn = gfn; arch.direct_map = vcpu->arch.mmu.direct_map; + arch.cr3 = vcpu->arch.mmu.get_cr3 (vcpu);return kvm_setup_async_pf (vcpu, gva, gfn, &arch); }
arch/x86/kvm/paging_tmpl.h +23 -11
@@ -116,7 +116,7 @@ static unsigned FNAME(gpte_access)(struct kvm_vcpu *vcpu, pt_element_t gpte)*/ static int FNAME (walk_addr_generic )(struct guest_walker *walker,struct kvm_vcpu *vcpu,struct kvm_mmu *mmu, -gva_t addr,u32 access) +gva_t addr,u32 access,bool prefault) {pt_element_t pte;gfn_t table_gfn;
@@ -194,6 +194,13 @@ walk:#endif if (!eperm && !rsvd_fault && !(pte &PT_ACCESSED_MASK )) { +/* +* Don't set gpte accessed bit if it's on +* speculative path. +*/ +if (prefault) + goto error; +trace_kvm_mmu_set_accessed_bit (table_gfn, index,sizeof (pte)); if (FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn,
@@ -287,10 +294,11 @@ error: }static int FNAME (walk_addr )(struct guest_walker *walker, -struct kvm_vcpu *vcpu,gva_t addr,u32 access) +struct kvm_vcpu *vcpu,gva_t addr, +u32 access,bool prefault) {return FNAME (walk_addr_generic)(walker, vcpu, &vcpu->arch.mmu, addr, - access); + access, prefault); } static int FNAME(walk_addr_nested)(struct guest_walker *walker,
@@ -298,7 +306,7 @@ static int FNAME(walk_addr_nested)(struct guest_walker *walker, u32 access) {return FNAME (walk_addr_generic)(walker, vcpu, &vcpu->arch.nested_mmu, - addr, access); + addr, access, false); } static bool FNAME(prefetch_invalid_gpte)(struct kvm_vcpu *vcpu,
@@ -438,7 +446,8 @@ static void FNAME(pte_prefetch)(struct kvm_vcpu *vcpu, struct guest_walker *gw,static u64 *FNAME (fetch )(struct kvm_vcpu *vcpu,gva_t addr,struct guest_walker *gw,int user_fault,int write_fault,int hlevel, -int *ptwrite,pfn_t pfn,bool map_writable) +int *ptwrite,pfn_t pfn,bool map_writable, +bool prefault) {unsigned access = gw->pt_access;struct kvm_mmu_page *sp =NULL ;
@@ -512,7 +521,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,mmu_set_spte (vcpu, it.sptep, access, gw->pte_access & access, user_fault, write_fault, dirty, ptwrite, it.level, - gw->gfn, pfn, false, map_writable); + gw->gfn, pfn, prefault, map_writable);FNAME (pte_prefetch)(vcpu, gw, it.sptep);return it.sptep;
@@ -561,15 +570,18 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code,/* * Look up the guest pte for the faulting address. */ - r =FNAME (walk_addr)(&walker, vcpu, addr, error_code); + r =FNAME (walk_addr)(&walker, vcpu, addr, error_code, prefault);/* * The page is not mapped by the guest. Let the guest handle it. */ if (!r) {pgprintk ("%s: guest page fault\n" , __func__); -inject_page_fault (vcpu); - vcpu->arch.last_pt_write_count =0 ;/* reset fork detector */ +if (!prefault) { +inject_page_fault (vcpu); +/* reset fork detector */ + vcpu->arch.last_pt_write_count =0 ; + }return 0 ; }
@@ -599,7 +611,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, u32 error_code,trace_kvm_mmu_audit (vcpu,AUDIT_PRE_PAGE_FAULT );kvm_mmu_free_some_pages (vcpu); sptep =FNAME (fetch)(vcpu, addr, &walker, user_fault, write_fault, - level, &write_pt, pfn, map_writable); + level, &write_pt, pfn, map_writable, prefault); (void )sptep;pgprintk ("%s: shadow pte %p %llx ptwrite %d\n" , __func__, sptep, *sptep, write_pt);
@@ -685,7 +697,7 @@ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr, u32 access,gpa_t gpa =UNMAPPED_GVA ;int r; - r =FNAME (walk_addr)(&walker, vcpu, vaddr, access); + r =FNAME (walk_addr)(&walker, vcpu, vaddr, access, false);if (r) { gpa =gfn_to_gpa (walker.gfn);
arch/x86/kvm/x86.c +5 -1
@@ -6183,7 +6183,7 @@ void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu, struct kvm_async_pf *work) {int r; -if (!vcpu->arch.mmu.direct_map || !work->arch.direct_map || +if ((vcpu->arch.mmu.direct_map != work->arch.direct_map) ||is_error_page (work->page))return ;
@@ -6191,6 +6191,10 @@ void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu, struct kvm_async_pf *work)if (unlikely (r))return ; +if (!vcpu->arch.mmu.direct_map && + work->arch.cr3 != vcpu->arch.mmu.get_cr3 (vcpu)) +return ; + vcpu->arch.mmu.page_fault (vcpu, work->gva,0 , true); }
Signature · 1 line
1.7.0.4
Quoted 9 lines · Xiao Guangrong
It's the speculative path if '
no_apf= 1' and we will specially handle this speculative path in the later patch, so 'prefault' is better to fit the senseSigned-off-by Xiao Guangrong <[email protected]>--- arch/x86/include/asm/kvm_host.h | 3 ++- arch/x86/kvm/mmu.c | 18 +++++++++--------- arch/x86/kvm/paging_tmpl.h | 4 ++-- 3 files changed, 13 insertions(+), 12 deletions(-)
Looks good to me. Avi, Gleb?
Quoted 4 lines · Marcelo Tosatti
Quoted 3 lines · Xiao Guangrong
It's the speculative path if '
no_apf= 1' and we will specially handle this speculative path in the later patch, so 'prefault' is better to fit the sense
Quoted 8 lines
Quoted 6 lines
Signed-off-by Xiao Guangrong <[email protected]>--- arch/x86/include/asm/kvm_host.h | 3 ++- arch/x86/kvm/mmu.c | 18 +++++++++--------- arch/x86/kvm/paging_tmpl.h | 4 ++-- 3 files changed, 13 insertions(+), 12 deletions(-)Looks good to me. Avi, Gleb?
Looks mostly OK to me too. Third patch check only cr3 but cr4 & efer can affect paging too, but since page fault is not injected anyway in case of an error and for most guests cr4 & efer shouldn't change frequently I guess this is OK.
--
Gleb.