]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
x86/l1tf: Handle EPT disabled state proper
authorThomas Gleixner <tglx@linutronix.de>
Fri, 13 Jul 2018 14:23:18 +0000 (16:23 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 15 Aug 2018 16:12:55 +0000 (18:12 +0200)
commit a7b9020b06ec6d7c3f3b0d4ef1a9eba12654f4f7 upstream

If Extended Page Tables (EPT) are disabled or not supported, no L1D
flushing is required. The setup function can just avoid setting up the L1D
flush for the EPT=n case.

Invoke it after the hardware setup has be done and enable_ept has the
correct state and expose the EPT disabled state in the mitigation status as
well.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Jiri Kosina <jkosina@suse.cz>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com>
Link: https://lkml.kernel.org/r/20180713142322.612160168@linutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/include/asm/vmx.h
arch/x86/kernel/cpu/bugs.c
arch/x86/kvm/vmx.c

index 6b9e556acef7beea6405e0d796d82a746839bbd7..7b049281716978abc073f44d5f4b24411bfff74e 100644 (file)
@@ -576,6 +576,7 @@ enum vmx_l1d_flush_state {
        VMENTER_L1D_FLUSH_NEVER,
        VMENTER_L1D_FLUSH_COND,
        VMENTER_L1D_FLUSH_ALWAYS,
+       VMENTER_L1D_FLUSH_EPT_DISABLED,
 };
 
 extern enum vmx_l1d_flush_state l1tf_vmx_mitigation;
index 511e6d63d9dd4b2c5f7cffff6137a721c1f7404e..b75828cf7715bf4d6145f5dbef7ad1c0365116ce 100644 (file)
@@ -676,10 +676,11 @@ static void __init l1tf_select_mitigation(void)
 
 #if IS_ENABLED(CONFIG_KVM_INTEL)
 static const char *l1tf_vmx_states[] = {
-       [VMENTER_L1D_FLUSH_AUTO]        = "auto",
-       [VMENTER_L1D_FLUSH_NEVER]       = "vulnerable",
-       [VMENTER_L1D_FLUSH_COND]        = "conditional cache flushes",
-       [VMENTER_L1D_FLUSH_ALWAYS]      = "cache flushes",
+       [VMENTER_L1D_FLUSH_AUTO]                = "auto",
+       [VMENTER_L1D_FLUSH_NEVER]               = "vulnerable",
+       [VMENTER_L1D_FLUSH_COND]                = "conditional cache flushes",
+       [VMENTER_L1D_FLUSH_ALWAYS]              = "cache flushes",
+       [VMENTER_L1D_FLUSH_EPT_DISABLED]        = "EPT disabled",
 };
 
 static ssize_t l1tf_show_state(char *buf)
index ba4ae2bc854f4f46a91638c18775804ed8f4f066..8ddc6b794a945f6bf147ec73c0e6a23db189179b 100644 (file)
@@ -12502,6 +12502,11 @@ static int __init vmx_setup_l1d_flush(void)
        if (!boot_cpu_has_bug(X86_BUG_L1TF))
                return 0;
 
+       if (!enable_ept) {
+               l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_EPT_DISABLED;
+               return 0;
+       }
+
        l1tf_vmx_mitigation = vmentry_l1d_flush;
 
        if (vmentry_l1d_flush == VMENTER_L1D_FLUSH_NEVER)
@@ -12528,18 +12533,35 @@ static void vmx_cleanup_l1d_flush(void)
        l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_AUTO;
 }
 
+
+static void vmx_exit(void)
+{
+#ifdef CONFIG_KEXEC_CORE
+       RCU_INIT_POINTER(crash_vmclear_loaded_vmcss, NULL);
+       synchronize_rcu();
+#endif
+
+       kvm_exit();
+
+       vmx_cleanup_l1d_flush();
+}
+module_exit(vmx_exit)
+
 static int __init vmx_init(void)
 {
        int r;
 
-       r = vmx_setup_l1d_flush();
+       r = kvm_init(&vmx_x86_ops, sizeof(struct vcpu_vmx),
+                    __alignof__(struct vcpu_vmx), THIS_MODULE);
        if (r)
                return r;
 
-       r = kvm_init(&vmx_x86_ops, sizeof(struct vcpu_vmx),
-                    __alignof__(struct vcpu_vmx), THIS_MODULE);
+       /*
+        * Must be called after kvm_init() so enable_ept is properly set up
+        */
+       r = vmx_setup_l1d_flush();
        if (r) {
-               vmx_cleanup_l1d_flush();
+               vmx_exit();
                return r;
        }
 
@@ -12550,18 +12572,4 @@ static int __init vmx_init(void)
 
        return 0;
 }
-
-static void __exit vmx_exit(void)
-{
-#ifdef CONFIG_KEXEC_CORE
-       RCU_INIT_POINTER(crash_vmclear_loaded_vmcss, NULL);
-       synchronize_rcu();
-#endif
-
-       kvm_exit();
-
-       vmx_cleanup_l1d_flush();
-}
-
 module_init(vmx_init)
-module_exit(vmx_exit)