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.

Reply via email to