From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ed White Subject: [PATCH v5 02/15] VMX: VMFUNC and #VE definitions and detection. Date: Mon, 13 Jul 2015 17:14:50 -0700 Message-ID: <1436832903-12639-3-git-send-email-edmund.h.white@intel.com> References: <1436832903-12639-1-git-send-email-edmund.h.white@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1436832903-12639-1-git-send-email-edmund.h.white@intel.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xen.org Cc: Ravi Sahita , Wei Liu , George Dunlap , Ian Jackson , Tim Deegan , Ed White , Jan Beulich , Andrew Cooper , tlengyel@novetta.com, Daniel De Graaf List-Id: xen-devel@lists.xenproject.org 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 Reviewed-by: Andrew Cooper Acked-by: George Dunlap Acked-by: Jun Nakajima --- 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