From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ed White Subject: [PATCH 01/11] VMX: VMFUNC and #VE definitions and detection. Date: Fri, 9 Jan 2015 13:26:31 -0800 Message-ID: <1420838801-11704-2-git-send-email-edmund.h.white@intel.com> References: <1420838801-11704-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: <1420838801-11704-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: keir@xen.org, ian.campbell@citrix.com, tim@xen.org, ian.jackson@eu.citrix.com, Ed White , jbeulich@suse.com 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. Everything can be force-disabled globally by specifying vmfunc=0 on the Xen command line. 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 --- docs/misc/xen-command-line.markdown | 7 +++++++ xen/arch/x86/hvm/vmx/vmcs.c | 40 +++++++++++++++++++++++++++++++++++++ xen/arch/x86/mm/p2m-ept.c | 1 - xen/include/asm-x86/hvm/vmx/vmcs.h | 16 +++++++++++++++ xen/include/asm-x86/hvm/vmx/vmx.h | 13 +++++++++++- xen/include/asm-x86/msr-index.h | 1 + 6 files changed, 76 insertions(+), 2 deletions(-) diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown index 152ae03..00fbae7 100644 --- a/docs/misc/xen-command-line.markdown +++ b/docs/misc/xen-command-line.markdown @@ -1305,6 +1305,13 @@ The optional `keep` parameter causes Xen to continue using the vga console even after dom0 has been started. The default behaviour is to relinquish control to dom0. +### vmfunc (Intel) +> `= ` + +> Default: `true` + +Use VMFUNC and #VE support if available. + ### vpid (Intel) > `= ` diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 9d8033e..4274e92 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -50,6 +50,9 @@ boolean_param("unrestricted_guest", opt_unrestricted_guest_enabled); static bool_t __read_mostly opt_apicv_enabled = 1; boolean_param("apicv", opt_apicv_enabled); +static bool_t __read_mostly opt_vmfunc_enabled = 1; +boolean_param("vmfunc", opt_vmfunc_enabled); + /* * These two parameters are used to config the controls for Pause-Loop Exiting: * ple_gap: upper bound on the amount of time between two successive @@ -71,6 +74,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, @@ -110,6 +115,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, "Virtualization Exceptions"); #undef P if ( !printed ) @@ -154,6 +161,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); @@ -207,6 +215,9 @@ static int vmx_init_vmcs_config(void) opt |= SECONDARY_EXEC_ENABLE_VPID; if ( opt_unrestricted_guest_enabled ) opt |= SECONDARY_EXEC_UNRESTRICTED_GUEST; + if ( opt_vmfunc_enabled ) + opt |= SECONDARY_EXEC_ENABLE_VM_FUNCTIONS | + SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS; /* * "APIC Register Virtualization" and "Virtual Interrupt Delivery" @@ -296,6 +307,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( @@ -316,6 +345,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. */ @@ -352,6 +384,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)) ) { @@ -921,6 +956,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 */ diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c index 15c6e83..eb8b5f9 100644 --- a/xen/arch/x86/mm/p2m-ept.c +++ b/xen/arch/x86/mm/p2m-ept.c @@ -244,7 +244,6 @@ static int ept_split_super_page(struct p2m_domain *p2m, ept_entry_t *ept_entry, epte->mfn += i * trunk; epte->snp = (iommu_enabled && iommu_snoop); ASSERT(!epte->rsvd1); - ASSERT(!epte->avail3); ept_p2m_type_to_flags(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 6a99dca..c6db13f 100644 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h @@ -213,7 +213,9 @@ 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_VM_FUNCTIONS 0x00002000 #define SECONDARY_EXEC_ENABLE_VMCS_SHADOWING 0x00004000 +#define SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS 0x00040000 extern u32 vmx_secondary_exec_control; #define VMX_EPT_EXEC_ONLY_SUPPORTED 0x00000001 @@ -273,6 +275,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 VMCS_RID_TYPE_MASK 0x80000000 @@ -302,10 +308,14 @@ 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. */ enum vmcs_field { VIRTUAL_PROCESSOR_ID = 0x00000000, POSTED_INTR_NOTIFICATION_VECTOR = 0x00000002, + EPTP_INDEX = 0x00000004, GUEST_ES_SELECTOR = 0x00000800, GUEST_CS_SELECTOR = 0x00000802, GUEST_SS_SELECTOR = 0x00000804, @@ -342,14 +352,20 @@ enum vmcs_field { APIC_ACCESS_ADDR_HIGH = 0x00002015, PI_DESC_ADDR = 0x00002016, PI_DESC_ADDR_HIGH = 0x00002017, + VM_FUNCTION_CONTROL = 0x00002018, + VM_FUNCTION_CONTROL_HIGH = 0x00002019, EPT_POINTER = 0x0000201a, EPT_POINTER_HIGH = 0x0000201b, EOI_EXIT_BITMAP0 = 0x0000201c, #define EOI_EXIT_BITMAP(n) (EOI_EXIT_BITMAP0 + (n) * 2) /* n = 0...3 */ + EPTP_LIST_ADDR = 0x00002024, + EPTP_LIST_ADDR_HIGH = 0x00002025, VMREAD_BITMAP = 0x00002026, VMREAD_BITMAP_HIGH = 0x00002027, VMWRITE_BITMAP = 0x00002028, VMWRITE_BITMAP_HIGH = 0x00002029, + VIRT_EXCEPTION_INFO = 0x0000202a, + VIRT_EXCEPTION_INFO_HIGH = 0x0000202b, GUEST_PHYSICAL_ADDRESS = 0x00002400, GUEST_PHYSICAL_ADDRESS_HIGH = 0x00002401, VMCS_LINK_POINTER = 0x00002800, diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h index c8bb548..8bae195 100644 --- a/xen/include/asm-x86/hvm/vmx/vmx.h +++ b/xen/include/asm-x86/hvm/vmx/vmx.h @@ -46,7 +46,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; @@ -185,6 +185,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 /* * Interruption-information format @@ -550,4 +551,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