Linux kernel 4.6 and later make use of this instruction and crash if we do not allow it. It flushes TLB mappings, but only on the caller's logical CPU.
Signed-off-by: Jan Kiszka <[email protected]> --- Grmbl, just wanted to quickly test an "all fresh" box... hypervisor/arch/x86/include/asm/processor.h | 1 + hypervisor/arch/x86/include/asm/vmx.h | 1 + hypervisor/arch/x86/vmx.c | 17 +++++++++-------- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/hypervisor/arch/x86/include/asm/processor.h b/hypervisor/arch/x86/include/asm/processor.h index 85e41b3..6c50d27 100644 --- a/hypervisor/arch/x86/include/asm/processor.h +++ b/hypervisor/arch/x86/include/asm/processor.h @@ -28,6 +28,7 @@ #define X86_FEATURE_HYPERVISOR (1 << 31) /* leaf 0x07, subleaf 0, EBX */ +#define X86_FEATURE_INVPCID (1 << 10) #define X86_FEATURE_CAT (1 << 15) /* leaf 0x80000001, ECX */ diff --git a/hypervisor/arch/x86/include/asm/vmx.h b/hypervisor/arch/x86/include/asm/vmx.h index 775ef3f..66795c1 100644 --- a/hypervisor/arch/x86/include/asm/vmx.h +++ b/hypervisor/arch/x86/include/asm/vmx.h @@ -226,6 +226,7 @@ enum vmx_state { VMXOFF = 0, VMXON, VMCS_READY }; #define SECONDARY_EXEC_ENABLE_EPT (1UL << 1) #define SECONDARY_EXEC_RDTSCP (1UL << 3) #define SECONDARY_EXEC_UNRESTRICTED_GUEST (1UL << 7) +#define SECONDARY_EXEC_INVPCID (1UL << 12) #define VM_EXIT_HOST_ADDR_SPACE_SIZE (1UL << 9) #define VM_EXIT_SAVE_IA32_PAT (1UL << 18) diff --git a/hypervisor/arch/x86/vmx.c b/hypervisor/arch/x86/vmx.c index f5cd8ca..3fe6e1d 100644 --- a/hypervisor/arch/x86/vmx.c +++ b/hypervisor/arch/x86/vmx.c @@ -80,7 +80,7 @@ static u8 __attribute__((aligned(PAGE_SIZE))) msr_bitmap[][0x2000/8] = { }; static u8 __attribute__((aligned(PAGE_SIZE))) apic_access_page[PAGE_SIZE]; static struct paging ept_paging[EPT_PAGE_DIR_LEVELS]; -static u32 enable_rdtscp; +static u32 secondary_exec_addon; static unsigned long cr_maybe1[2], cr_required1[2]; static bool vmxon(struct per_cpu *cpu_data) @@ -233,12 +233,13 @@ static int vmx_check_features(void) !(vmx_proc_ctrl2 & SECONDARY_EXEC_UNRESTRICTED_GUEST)) return trace_error(-EIO); - /* require RDTSCP if present in CPUID */ - if (cpuid_edx(0x80000001, 0) & X86_FEATURE_RDTSCP) { - enable_rdtscp = SECONDARY_EXEC_RDTSCP; - if (!(vmx_proc_ctrl2 & SECONDARY_EXEC_RDTSCP)) - return trace_error(-EIO); - } + /* require RDTSCP and INVPCID if present in CPUID */ + if (cpuid_edx(0x80000001, 0) & X86_FEATURE_RDTSCP) + secondary_exec_addon |= SECONDARY_EXEC_RDTSCP; + if (cpuid_ebx(0x07, 0) & X86_FEATURE_INVPCID) + secondary_exec_addon |= SECONDARY_EXEC_INVPCID; + if ((vmx_proc_ctrl2 & secondary_exec_addon) != secondary_exec_addon) + return trace_error(-EIO); /* require PAT and EFER save/restore */ vmx_entry_ctrl = read_msr(MSR_IA32_VMX_ENTRY_CTLS) >> 32; @@ -565,7 +566,7 @@ static bool vmcs_setup(struct per_cpu *cpu_data) val = read_msr(MSR_IA32_VMX_PROCBASED_CTLS2); val |= SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | SECONDARY_EXEC_ENABLE_EPT | SECONDARY_EXEC_UNRESTRICTED_GUEST | - enable_rdtscp; + secondary_exec_addon; ok &= vmcs_write32(SECONDARY_VM_EXEC_CONTROL, val); ok &= vmcs_write64(APIC_ACCESS_ADDR, -- 2.1.4 -- You received this message because you are subscribed to the Google Groups "Jailhouse" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
