[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v5 rebased 2/4] nested vmx: use VMREAD/VMWRITE to construct vVMCS if enabled VMCS shadowing
Acked-by Eddie Dong <eddie.dong@xxxxxxxxx> > -----Original Message----- > From: Xu, Dongxiao > Sent: Wednesday, January 23, 2013 10:32 PM > To: xen-devel@xxxxxxxxxxxxxxxxxxx > Cc: Dong, Eddie; Nakajima, Jun; Zhang, Xiantao; JBeulich@xxxxxxxx > Subject: [PATCH v5 rebased 2/4] nested vmx: use VMREAD/VMWRITE to > construct vVMCS if enabled VMCS shadowing > > Before the VMCS shadowing feature, we use memory operation to build up > the virtual VMCS. This does work since this virtual VMCS will never be > loaded into real hardware. However after we introduce the VMCS > shadowing feature, this VMCS will be loaded into hardware, which > requires all fields in the VMCS accessed by VMREAD/VMWRITE. > > Besides, the virtual VMCS revision identifer should also meet the > hardware's requirement, instead of using a faked one. > > Signed-off-by: Dongxiao Xu <dongxiao.xu@xxxxxxxxx> > --- > xen/arch/x86/hvm/vmx/vmcs.c | 29 > +++++++++++++++++++++++++++++ > xen/arch/x86/hvm/vmx/vvmx.c | 20 ++++++++++++++++---- > xen/include/asm-x86/hvm/vmx/vmcs.h | 5 +++++ > xen/include/asm-x86/hvm/vmx/vvmx.h | 16 ++++++++++++---- > 4 files changed, 62 insertions(+), 8 deletions(-) > > diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c > index de22e03..82a8d91 100644 > --- a/xen/arch/x86/hvm/vmx/vmcs.c > +++ b/xen/arch/x86/hvm/vmx/vmcs.c > @@ -725,6 +725,35 @@ void vmx_vmcs_switch(struct vmcs_struct *from, > struct vmcs_struct *to) > spin_unlock(&vmx->vmcs_lock); > } > > +void virtual_vmcs_enter(void *vvmcs) > +{ > + __vmptrld(pfn_to_paddr(domain_page_map_to_mfn(vvmcs))); > +} > + > +void virtual_vmcs_exit(void *vvmcs) > +{ > + __vmpclear(pfn_to_paddr(domain_page_map_to_mfn(vvmcs))); > + __vmptrld(virt_to_maddr(this_cpu(current_vmcs))); > +} > + > +u64 virtual_vmcs_vmread(void *vvmcs, u32 vmcs_encoding) > +{ > + u64 res; > + > + virtual_vmcs_enter(vvmcs); > + res = __vmread(vmcs_encoding); > + virtual_vmcs_exit(vvmcs); > + > + return res; > +} > + > +void virtual_vmcs_vmwrite(void *vvmcs, u32 vmcs_encoding, u64 val) > +{ > + virtual_vmcs_enter(vvmcs); > + __vmwrite(vmcs_encoding, val); > + virtual_vmcs_exit(vvmcs); > +} > + > static int construct_vmcs(struct vcpu *v) > { > struct domain *d = v->domain; > diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c > index cd8bb90..8000f84 100644 > --- a/xen/arch/x86/hvm/vmx/vvmx.c > +++ b/xen/arch/x86/hvm/vmx/vvmx.c > @@ -175,7 +175,7 @@ static int vvmcs_offset(u32 width, u32 type, u32 > index) > return offset; > } > > -u64 __get_vvmcs(void *vvmcs, u32 vmcs_encoding) > +u64 __get_vvmcs_virtual(void *vvmcs, u32 vmcs_encoding) > { > union vmcs_encoding enc; > u64 *content = (u64 *) vvmcs; > @@ -205,7 +205,12 @@ u64 __get_vvmcs(void *vvmcs, u32 vmcs_encoding) > return res; > } > > -void __set_vvmcs(void *vvmcs, u32 vmcs_encoding, u64 val) > +u64 __get_vvmcs_real(void *vvmcs, u32 vmcs_encoding) > +{ > + return virtual_vmcs_vmread(vvmcs, vmcs_encoding); > +} > + > +void __set_vvmcs_virtual(void *vvmcs, u32 vmcs_encoding, u64 val) > { > union vmcs_encoding enc; > u64 *content = (u64 *) vvmcs; > @@ -241,6 +246,11 @@ void __set_vvmcs(void *vvmcs, u32 vmcs_encoding, > u64 val) > content[offset] = res; > } > > +void __set_vvmcs_real(void *vvmcs, u32 vmcs_encoding, u64 val) > +{ > + virtual_vmcs_vmwrite(vvmcs, vmcs_encoding, val); > +} > + > static unsigned long reg_read(struct cpu_user_regs *regs, > enum vmx_regs_enc index) > { > @@ -1568,10 +1578,11 @@ int nvmx_handle_invvpid(struct cpu_user_regs > *regs) > */ > int nvmx_msr_read_intercept(unsigned int msr, u64 *msr_content) > { > + struct vcpu *v = current; > u64 data = 0, host_data = 0; > int r = 1; > > - if ( !nestedhvm_enabled(current->domain) ) > + if ( !nestedhvm_enabled(v->domain) ) > return 0; > > rdmsrl(msr, host_data); > @@ -1581,7 +1592,8 @@ int nvmx_msr_read_intercept(unsigned int msr, > u64 *msr_content) > */ > switch (msr) { > case MSR_IA32_VMX_BASIC: > - data = (host_data & (~0ul << 32)) | VVMCS_REVISION; > + data = (host_data & (~0ul << 32)) | > + ((v->arch.hvm_vmx.vmcs)->vmcs_revision_id); > break; > case MSR_IA32_VMX_PINBASED_CTLS: > case MSR_IA32_VMX_TRUE_PINBASED_CTLS: > diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h > b/xen/include/asm-x86/hvm/vmx/vmcs.h > index 9ff741f..652dc21 100644 > --- a/xen/include/asm-x86/hvm/vmx/vmcs.h > +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h > @@ -244,6 +244,7 @@ extern bool_t cpu_has_vmx_ins_outs_instr_info; > (vmx_secondary_exec_control & > SECONDARY_EXEC_APIC_REGISTER_VIRT) > #define cpu_has_vmx_virtual_intr_delivery \ > (vmx_secondary_exec_control & > SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY) > +#define cpu_has_vmx_vmcs_shadowing 0 > > /* GUEST_INTERRUPTIBILITY_INFO flags. */ > #define VMX_INTR_SHADOW_STI 0x00000001 > @@ -436,6 +437,10 @@ void vmx_vmcs_switch(struct vmcs_struct *from, > struct vmcs_struct *to); > void vmx_set_eoi_exit_bitmap(struct vcpu *v, u8 vector); > void vmx_clear_eoi_exit_bitmap(struct vcpu *v, u8 vector); > int vmx_check_msr_bitmap(unsigned long *msr_bitmap, u32 msr, int > access_type); > +void virtual_vmcs_enter(void *vvmcs); > +void virtual_vmcs_exit(void *vvmcs); > +u64 virtual_vmcs_vmread(void *vvmcs, u32 vmcs_encoding); > +void virtual_vmcs_vmwrite(void *vvmcs, u32 vmcs_encoding, u64 val); > > #endif /* ASM_X86_HVM_VMX_VMCS_H__ */ > > diff --git a/xen/include/asm-x86/hvm/vmx/vvmx.h > b/xen/include/asm-x86/hvm/vmx/vvmx.h > index 89e839f..73a67cc 100644 > --- a/xen/include/asm-x86/hvm/vmx/vvmx.h > +++ b/xen/include/asm-x86/hvm/vmx/vvmx.h > @@ -152,8 +152,6 @@ nvmx_hap_walk_L1_p2m(struct vcpu *v, paddr_t > L2_gpa, paddr_t *L1_gpa, > * > */ > > -#define VVMCS_REVISION 0x40000001u > - > struct vvmcs_header { > u32 revision; > u32 abort; > @@ -185,8 +183,18 @@ enum vvmcs_encoding_type { > VVMCS_TYPE_HSTATE, > }; > > -u64 __get_vvmcs(void *vvmcs, u32 vmcs_encoding); > -void __set_vvmcs(void *vvmcs, u32 vmcs_encoding, u64 val); > +u64 __get_vvmcs_virtual(void *vvmcs, u32 vmcs_encoding); > +u64 __get_vvmcs_real(void *vvmcs, u32 vmcs_encoding); > +void __set_vvmcs_virtual(void *vvmcs, u32 vmcs_encoding, u64 val); > +void __set_vvmcs_real(void *vvmcs, u32 vmcs_encoding, u64 val); > + > +#define __get_vvmcs(_vvmcs, _vmcs_encoding) \ > + (cpu_has_vmx_vmcs_shadowing ? __get_vvmcs_real(_vvmcs, > _vmcs_encoding) \ > + : __get_vvmcs_virtual(_vvmcs, > _vmcs_encoding)) > + > +#define __set_vvmcs(_vvmcs, _vmcs_encoding, _val) \ > + (cpu_has_vmx_vmcs_shadowing ? __set_vvmcs_real(_vvmcs, > _vmcs_encoding, _val) \ > + : __set_vvmcs_virtual(_vvmcs, > _vmcs_encoding, _val)) > > uint64_t get_shadow_eptp(struct vcpu *v); > > -- > 1.7.1 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |