[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.