[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v3 02/13] VMX: VMFUNC and #VE definitions and detection.



On Wed, Jul 1, 2015 at 7:09 PM, Ed White <edmund.h.white@xxxxxxxxx> wrote:
> Currently, neither is enabled globally but may be enabled on a per-VCPU
> basis by the altp2m code.
>
> Remove the check for EPTE bit 63 == zero in ept_split_super_page(), as
> that bit is now hardware-defined.
>
> Signed-off-by: Ed White <edmund.h.white@xxxxxxxxx>
>
> Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>

Acked-by: George Dunlap <george.dunlap@xxxxxxxxxxxxx>

> ---
>  xen/arch/x86/hvm/vmx/vmcs.c        | 42 
> +++++++++++++++++++++++++++++++++++---
>  xen/arch/x86/mm/p2m-ept.c          |  1 -
>  xen/include/asm-x86/hvm/vmx/vmcs.h | 14 +++++++++++--
>  xen/include/asm-x86/hvm/vmx/vmx.h  | 13 +++++++++++-
>  xen/include/asm-x86/msr-index.h    |  1 +
>  5 files changed, 64 insertions(+), 7 deletions(-)
>
> diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
> index 4c5ceb5..bc1cabd 100644
> --- a/xen/arch/x86/hvm/vmx/vmcs.c
> +++ b/xen/arch/x86/hvm/vmx/vmcs.c
> @@ -101,6 +101,8 @@ u32 vmx_secondary_exec_control __read_mostly;
>  u32 vmx_vmexit_control __read_mostly;
>  u32 vmx_vmentry_control __read_mostly;
>  u64 vmx_ept_vpid_cap __read_mostly;
> +u64 vmx_vmfunc __read_mostly;
> +bool_t vmx_virt_exception __read_mostly;
>
>  const u32 vmx_introspection_force_enabled_msrs[] = {
>      MSR_IA32_SYSENTER_EIP,
> @@ -140,6 +142,8 @@ static void __init vmx_display_features(void)
>      P(cpu_has_vmx_virtual_intr_delivery, "Virtual Interrupt Delivery");
>      P(cpu_has_vmx_posted_intr_processing, "Posted Interrupt Processing");
>      P(cpu_has_vmx_vmcs_shadowing, "VMCS shadowing");
> +    P(cpu_has_vmx_vmfunc, "VM Functions");
> +    P(cpu_has_vmx_virt_exceptions, "Virtualisation Exceptions");
>      P(cpu_has_vmx_pml, "Page Modification Logging");
>  #undef P
>
> @@ -185,6 +189,7 @@ static int vmx_init_vmcs_config(void)
>      u64 _vmx_misc_cap = 0;
>      u32 _vmx_vmexit_control;
>      u32 _vmx_vmentry_control;
> +    u64 _vmx_vmfunc = 0;
>      bool_t mismatch = 0;
>
>      rdmsr(MSR_IA32_VMX_BASIC, vmx_basic_msr_low, vmx_basic_msr_high);
> @@ -230,7 +235,9 @@ static int vmx_init_vmcs_config(void)
>                 SECONDARY_EXEC_ENABLE_EPT |
>                 SECONDARY_EXEC_ENABLE_RDTSCP |
>                 SECONDARY_EXEC_PAUSE_LOOP_EXITING |
> -               SECONDARY_EXEC_ENABLE_INVPCID);
> +               SECONDARY_EXEC_ENABLE_INVPCID |
> +               SECONDARY_EXEC_ENABLE_VM_FUNCTIONS |
> +               SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS);
>          rdmsrl(MSR_IA32_VMX_MISC, _vmx_misc_cap);
>          if ( _vmx_misc_cap & VMX_MISC_VMWRITE_ALL )
>              opt |= SECONDARY_EXEC_ENABLE_VMCS_SHADOWING;
> @@ -341,6 +348,24 @@ static int vmx_init_vmcs_config(void)
>            || !(_vmx_vmexit_control & VM_EXIT_ACK_INTR_ON_EXIT) )
>          _vmx_pin_based_exec_control  &= ~ PIN_BASED_POSTED_INTERRUPT;
>
> +    /* The IA32_VMX_VMFUNC MSR exists only when VMFUNC is available */
> +    if ( _vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VM_FUNCTIONS )
> +    {
> +        rdmsrl(MSR_IA32_VMX_VMFUNC, _vmx_vmfunc);
> +
> +        /*
> +         * VMFUNC leaf 0 (EPTP switching) must be supported.
> +         *
> +         * Or we just don't use VMFUNC.
> +         */
> +        if ( !(_vmx_vmfunc & VMX_VMFUNC_EPTP_SWITCHING) )
> +            _vmx_secondary_exec_control &= 
> ~SECONDARY_EXEC_ENABLE_VM_FUNCTIONS;
> +    }
> +
> +    /* Virtualization exceptions are only enabled if VMFUNC is enabled */
> +    if ( !(_vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VM_FUNCTIONS) 
> )
> +        _vmx_secondary_exec_control &= 
> ~SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS;
> +
>      min = 0;
>      opt = VM_ENTRY_LOAD_GUEST_PAT | VM_ENTRY_LOAD_BNDCFGS;
>      _vmx_vmentry_control = adjust_vmx_controls(
> @@ -361,6 +386,9 @@ static int vmx_init_vmcs_config(void)
>          vmx_vmentry_control        = _vmx_vmentry_control;
>          vmx_basic_msr              = ((u64)vmx_basic_msr_high << 32) |
>                                       vmx_basic_msr_low;
> +        vmx_vmfunc                 = _vmx_vmfunc;
> +        vmx_virt_exception         = !!(_vmx_secondary_exec_control &
> +                                       
> SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS);
>          vmx_display_features();
>
>          /* IA-32 SDM Vol 3B: VMCS size is never greater than 4kB. */
> @@ -397,6 +425,9 @@ static int vmx_init_vmcs_config(void)
>          mismatch |= cap_check(
>              "EPT and VPID Capability",
>              vmx_ept_vpid_cap, _vmx_ept_vpid_cap);
> +        mismatch |= cap_check(
> +            "VMFUNC Capability",
> +            vmx_vmfunc, _vmx_vmfunc);
>          if ( cpu_has_vmx_ins_outs_instr_info !=
>               !!(vmx_basic_msr_high & (VMX_BASIC_INS_OUT_INFO >> 32)) )
>          {
> @@ -967,6 +998,11 @@ static int construct_vmcs(struct vcpu *v)
>      /* Do not enable Monitor Trap Flag unless start single step debug */
>      v->arch.hvm_vmx.exec_control &= ~CPU_BASED_MONITOR_TRAP_FLAG;
>
> +    /* Disable VMFUNC and #VE for now: they may be enabled later by altp2m. 
> */
> +    v->arch.hvm_vmx.secondary_exec_control &=
> +        ~(SECONDARY_EXEC_ENABLE_VM_FUNCTIONS |
> +          SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS);
> +
>      if ( is_pvh_domain(d) )
>      {
>          /* Disable virtual apics, TPR */
> @@ -1790,9 +1826,9 @@ void vmcs_dump_vcpu(struct vcpu *v)
>          printk("PLE Gap=%08x Window=%08x\n",
>                 vmr32(PLE_GAP), vmr32(PLE_WINDOW));
>      if ( v->arch.hvm_vmx.secondary_exec_control &
> -         (SECONDARY_EXEC_ENABLE_VPID | SECONDARY_EXEC_ENABLE_VMFUNC) )
> +         (SECONDARY_EXEC_ENABLE_VPID | SECONDARY_EXEC_ENABLE_VM_FUNCTIONS) )
>          printk("Virtual processor ID = 0x%04x VMfunc controls = %016lx\n",
> -               vmr16(VIRTUAL_PROCESSOR_ID), vmr(VMFUNC_CONTROL));
> +               vmr16(VIRTUAL_PROCESSOR_ID), vmr(VM_FUNCTION_CONTROL));
>
>      vmx_vmcs_exit(v);
>  }
> diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c
> index 5133eb6..a6c9adf 100644
> --- a/xen/arch/x86/mm/p2m-ept.c
> +++ b/xen/arch/x86/mm/p2m-ept.c
> @@ -281,7 +281,6 @@ static int ept_split_super_page(struct p2m_domain *p2m, 
> ept_entry_t *ept_entry,
>          epte->sp = (level > 1);
>          epte->mfn += i * trunk;
>          epte->snp = (iommu_enabled && iommu_snoop);
> -        ASSERT(!epte->avail3);
>
>          ept_p2m_type_to_flags(p2m, epte, epte->sa_p2mt, epte->access);
>
> diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h 
> b/xen/include/asm-x86/hvm/vmx/vmcs.h
> index 1104bda..cb0ee6c 100644
> --- a/xen/include/asm-x86/hvm/vmx/vmcs.h
> +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
> @@ -222,9 +222,10 @@ extern u32 vmx_vmentry_control;
>  #define SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY    0x00000200
>  #define SECONDARY_EXEC_PAUSE_LOOP_EXITING       0x00000400
>  #define SECONDARY_EXEC_ENABLE_INVPCID           0x00001000
> -#define SECONDARY_EXEC_ENABLE_VMFUNC            0x00002000
> +#define SECONDARY_EXEC_ENABLE_VM_FUNCTIONS      0x00002000
>  #define SECONDARY_EXEC_ENABLE_VMCS_SHADOWING    0x00004000
>  #define SECONDARY_EXEC_ENABLE_PML               0x00020000
> +#define SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS   0x00040000
>  extern u32 vmx_secondary_exec_control;
>
>  #define VMX_EPT_EXEC_ONLY_SUPPORTED             0x00000001
> @@ -285,6 +286,10 @@ extern u32 vmx_secondary_exec_control;
>      (vmx_pin_based_exec_control & PIN_BASED_POSTED_INTERRUPT)
>  #define cpu_has_vmx_vmcs_shadowing \
>      (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VMCS_SHADOWING)
> +#define cpu_has_vmx_vmfunc \
> +    (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VM_FUNCTIONS)
> +#define cpu_has_vmx_virt_exceptions \
> +    (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS)
>  #define cpu_has_vmx_pml \
>      (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_PML)
>
> @@ -316,6 +321,9 @@ extern u64 vmx_basic_msr;
>  #define VMX_GUEST_INTR_STATUS_SUBFIELD_BITMASK  0x0FF
>  #define VMX_GUEST_INTR_STATUS_SVI_OFFSET        8
>
> +/* VMFUNC leaf definitions */
> +#define VMX_VMFUNC_EPTP_SWITCHING   (1ULL << 0)
> +
>  /* VMCS field encodings. */
>  #define VMCS_HIGH(x) ((x) | 1)
>  enum vmcs_field {
> @@ -350,12 +358,14 @@ enum vmcs_field {
>      VIRTUAL_APIC_PAGE_ADDR          = 0x00002012,
>      APIC_ACCESS_ADDR                = 0x00002014,
>      PI_DESC_ADDR                    = 0x00002016,
> -    VMFUNC_CONTROL                  = 0x00002018,
> +    VM_FUNCTION_CONTROL             = 0x00002018,
>      EPT_POINTER                     = 0x0000201a,
>      EOI_EXIT_BITMAP0                = 0x0000201c,
>  #define EOI_EXIT_BITMAP(n) (EOI_EXIT_BITMAP0 + (n) * 2) /* n = 0...3 */
> +    EPTP_LIST_ADDR                  = 0x00002024,
>      VMREAD_BITMAP                   = 0x00002026,
>      VMWRITE_BITMAP                  = 0x00002028,
> +    VIRT_EXCEPTION_INFO             = 0x0000202a,
>      GUEST_PHYSICAL_ADDRESS          = 0x00002400,
>      VMCS_LINK_POINTER               = 0x00002800,
>      GUEST_IA32_DEBUGCTL             = 0x00002802,
> diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h 
> b/xen/include/asm-x86/hvm/vmx/vmx.h
> index 35f804a..5b59d3c 100644
> --- a/xen/include/asm-x86/hvm/vmx/vmx.h
> +++ b/xen/include/asm-x86/hvm/vmx/vmx.h
> @@ -47,7 +47,7 @@ typedef union {
>          access      :   4,  /* bits 61:58 - p2m_access_t */
>          tm          :   1,  /* bit 62 - VT-d transient-mapping hint in
>                                 shared EPT/VT-d usage */
> -        avail3      :   1;  /* bit 63 - Software available 3 */
> +        suppress_ve :   1;  /* bit 63 - suppress #VE */
>      };
>      u64 epte;
>  } ept_entry_t;
> @@ -186,6 +186,7 @@ static inline unsigned long pi_get_pir(struct pi_desc 
> *pi_desc, int group)
>  #define EXIT_REASON_XSETBV              55
>  #define EXIT_REASON_APIC_WRITE          56
>  #define EXIT_REASON_INVPCID             58
> +#define EXIT_REASON_VMFUNC              59
>  #define EXIT_REASON_PML_FULL            62
>
>  /*
> @@ -554,4 +555,14 @@ void p2m_init_hap_data(struct p2m_domain *p2m);
>  #define EPT_L4_PAGETABLE_SHIFT      39
>  #define EPT_PAGETABLE_ENTRIES       512
>
> +/* #VE information page */
> +typedef struct {
> +    u32 exit_reason;
> +    u32 semaphore;
> +    u64 exit_qualification;
> +    u64 gla;
> +    u64 gpa;
> +    u16 eptp_index;
> +} ve_info_t;
> +
>  #endif /* __ASM_X86_HVM_VMX_VMX_H__ */
> diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h
> index 83f2f70..8069d60 100644
> --- a/xen/include/asm-x86/msr-index.h
> +++ b/xen/include/asm-x86/msr-index.h
> @@ -130,6 +130,7 @@
>  #define MSR_IA32_VMX_TRUE_PROCBASED_CTLS        0x48e
>  #define MSR_IA32_VMX_TRUE_EXIT_CTLS             0x48f
>  #define MSR_IA32_VMX_TRUE_ENTRY_CTLS            0x490
> +#define MSR_IA32_VMX_VMFUNC                     0x491
>  #define IA32_FEATURE_CONTROL_MSR                0x3a
>  #define IA32_FEATURE_CONTROL_MSR_LOCK                     0x0001
>  #define IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON_INSIDE_SMX  0x0002
> --
> 1.9.1
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@xxxxxxxxxxxxx
> http://lists.xen.org/xen-devel

_______________________________________________
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®.