mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
VMX: VMFUNC and #VE definitions and detection
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@intel.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> Acked-by: George Dunlap <george.dunlap@eu.citrix.com> Acked-by: Jun Nakajima <jun.nakajima@intel.com> Release-acked-by: Wei Liu <wei.liu2@citrix.com>
This commit is contained in:
1 parent
aace3f16d2
commit
69b830e5ff
5 files changed
+64
-7
No files matched your search
@@ -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);
|
||||
}
|
||||
|
||||
@@ -282,7 +282,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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
@@ -187,6 +187,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
|
||||
|
||||
/*
|
||||
@@ -555,4 +556,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__ */
|
||||
@@ -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
|
||||
|
||||