[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 4/4] x86/HVM: prefill cache with PDPTEs when possible
> -----Original Message----- > From: Jan Beulich [mailto:JBeulich@xxxxxxxx] > Sent: 25 September 2018 15:27 > To: xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxxx> > Cc: Andrew Cooper <Andrew.Cooper3@xxxxxxxxxx>; Paul Durrant > <Paul.Durrant@xxxxxxxxxx>; George Dunlap <George.Dunlap@xxxxxxxxxx> > Subject: [PATCH v3 4/4] x86/HVM: prefill cache with PDPTEs when possible > > Since strictly speaking it is incorrect for guest_walk_tables() to read > L3 entries during PAE page walks (they get loaded from memory only upon > CR3 loads and certain TLB flushes), try to overcome this where possible > by pre-loading the values from hardware into the cache. Sadly the > information is available in the EPT case only. On the positive side for > NPT the spec spells out that L3 entries are actually read on walks, so > us reading them is consistent with hardware behavior in that case. > > Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> > Reviewed-by: Kevin Tian <kevin.tian@xxxxxxxxx> Reviewed-by: Paul Durrant <paul.durrant@xxxxxxxxxx> > --- > v2: Re-base. > > --- a/xen/arch/x86/hvm/emulate.c > +++ b/xen/arch/x86/hvm/emulate.c > @@ -2385,6 +2385,23 @@ static int _hvm_emulate_one(struct hvm_e > > vio->mmio_retry = 0; > > + if ( !curr->arch.hvm.data_cache->num_ents && > + curr->arch.paging.mode->guest_levels == 3 ) > + { > + unsigned int i; > + > + for ( i = 0; i < 4; ++i ) > + { > + uint64_t pdpte; > + > + if ( hvm_read_pdpte(curr, i, &pdpte) ) > + hvmemul_write_cache(curr->arch.hvm.data_cache, > + (curr->arch.hvm.guest_cr[3] & > + (PADDR_MASK & ~0x1f)) + i * > sizeof(pdpte), > + 3, &pdpte, sizeof(pdpte)); > + } > + } > + > rc = x86_emulate(&hvmemul_ctxt->ctxt, ops); > if ( rc == X86EMUL_OKAY && vio->mmio_retry ) > rc = X86EMUL_RETRY; > --- a/xen/arch/x86/hvm/vmx/vmx.c > +++ b/xen/arch/x86/hvm/vmx/vmx.c > @@ -1368,6 +1368,25 @@ static void vmx_set_interrupt_shadow(str > __vmwrite(GUEST_INTERRUPTIBILITY_INFO, intr_shadow); > } > > +static bool read_pdpte(struct vcpu *v, unsigned int idx, uint64_t *pdpte) > +{ > + if ( !paging_mode_hap(v->domain) || !hvm_pae_enabled(v) || > + (v->arch.hvm.guest_efer & EFER_LMA) ) > + return false; > + > + if ( idx >= 4 ) > + { > + ASSERT_UNREACHABLE(); > + return false; > + } > + > + vmx_vmcs_enter(v); > + __vmread(GUEST_PDPTE(idx), pdpte); > + vmx_vmcs_exit(v); > + > + return true; > +} > + > static void vmx_load_pdptrs(struct vcpu *v) > { > unsigned long cr3 = v->arch.hvm.guest_cr[3]; > @@ -2466,6 +2485,8 @@ const struct hvm_function_table * __init > if ( cpu_has_vmx_ept_1gb ) > vmx_function_table.hap_capabilities |= HVM_HAP_SUPERPAGE_1GB; > > + vmx_function_table.read_pdpte = read_pdpte; > + > setup_ept_dump(); > } > > --- a/xen/include/asm-x86/hvm/hvm.h > +++ b/xen/include/asm-x86/hvm/hvm.h > @@ -146,6 +146,8 @@ struct hvm_function_table { > > void (*fpu_leave)(struct vcpu *v); > > + bool (*read_pdpte)(struct vcpu *v, unsigned int index, uint64_t > *pdpte); > + > int (*get_guest_pat)(struct vcpu *v, u64 *); > int (*set_guest_pat)(struct vcpu *v, u64); > > @@ -443,6 +445,12 @@ static inline unsigned long hvm_get_shad > return hvm_funcs.get_shadow_gs_base(v); > } > > +static inline bool hvm_read_pdpte(struct vcpu *v, unsigned int index, > uint64_t *pdpte) > +{ > + return hvm_funcs.read_pdpte && > + alternative_call(hvm_funcs.read_pdpte, v, index, pdpte); > +} > + > static inline bool hvm_get_guest_bndcfgs(struct vcpu *v, u64 *val) > { > return hvm_funcs.get_guest_bndcfgs && > > > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |