]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
x86/spectre_v2: Don't allow {ibrs,ipbp,lfence}_enabled to be toggled if retpoline
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Thu, 1 Feb 2018 17:25:54 +0000 (12:25 -0500)
committerJack Vogel <jack.vogel@oracle.com>
Thu, 8 Feb 2018 18:15:15 +0000 (10:15 -0800)
is enabled.

And also refresh the spectre_v2_enabled mode depending on whether
the sysfs knobs are turned on/off.

Preserve the ability to tweak IBPB if retpoline is enabled.

Orabug: 27477743
CVE: CVE-2017-5715

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Pavel Tatashin <pasha.tatashin@oracle.com>
arch/x86/include/asm/processor.h
arch/x86/kernel/cpu/bugs_64.c
arch/x86/kernel/cpu/spec_ctrl.c

index 540dd04d58f82eda7e0294bf899e3148d79a74f0..1d70864c19b01b3a5b79a9b10d193ec5a1dfec6f 100644 (file)
@@ -982,5 +982,6 @@ void df_debug(struct pt_regs *regs, long error_code);
 
 void disable_retpoline(void);
 bool retpoline_enabled(void);
+int refresh_set_spectre_v2_enabled(void);
 
 #endif /* _ASM_X86_PROCESSOR_H */
index dc062b3e559741647a4b9683189a9af31c771220..a363f9cab12deb95fb08e38ac51a7ff185f66c76 100644 (file)
@@ -134,6 +134,27 @@ bool retpoline_enabled(void)
        return false;
 }
 
+int refresh_set_spectre_v2_enabled(void)
+{
+       if (retpoline_enabled())
+               return false;
+
+       if (check_ibrs_inuse())
+               spectre_v2_enabled = SPECTRE_V2_IBRS;
+       else {
+               /*
+                * If that didn't work (say no microcode or noibrs), we end up using
+                * lfence on system calls/exceptions/parameters.
+                */
+               if (lfence_inuse)
+                       spectre_v2_enabled = SPECTRE_V2_IBRS_LFENCE;
+               else
+                       spectre_v2_enabled = SPECTRE_V2_NONE;
+       }
+
+       return true;
+}
+
 static void __init spec2_print_if_insecure(const char *reason)
 {
        if (boot_cpu_has_bug(X86_BUG_SPECTRE_V2))
@@ -377,9 +398,7 @@ ssize_t cpu_show_spectre_v2(struct device *dev,
        if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2))
                return sprintf(buf, "Not affected\n");
 
-       return sprintf(buf, "%s%s%s\n", spectre_v2_strings[spectre_v2_enabled],
-                                       ibrs_inuse ? "" /* As spectre_v2_strings has it. */ :
-                                               lfence_inuse ? " lfence " : "",
+       return sprintf(buf, "%s%s\n", spectre_v2_strings[spectre_v2_enabled],
                                        ibpb_inuse ? ", IBPB" : "");
 }
 #endif
index 9450e116bf598aeb69f9f8db6e3405bc9b17f165..93aa00cede932c7f946df4aecc3656d8a1d1dfd4 100644 (file)
@@ -56,6 +56,11 @@ static ssize_t ibrs_enabled_write(struct file *file,
        if (!ibrs_supported)
                return -ENODEV;
 
+       if (retpoline_enabled()) {
+               pr_warn("retpoline is enabled. Ignoring request to change ibrs state.\n");
+               return -EINVAL;
+       }
+
         len = min(count, sizeof(buf) - 1);
         if (copy_from_user(buf, user_buf, len))
                 return -EFAULT;
@@ -80,6 +85,7 @@ static ssize_t ibrs_enabled_write(struct file *file,
        } else {
                clear_ibrs_disabled();
        }
+       refresh_set_spectre_v2_enabled();
 
        mutex_unlock(&spec_ctrl_mutex);
        return count;
@@ -130,6 +136,8 @@ static ssize_t ibpb_enabled_write(struct file *file,
        else
                clear_ibpb_disabled();
 
+       refresh_set_spectre_v2_enabled();
+
        mutex_unlock(&spec_ctrl_mutex);
        return count;
 }
@@ -160,8 +168,9 @@ static ssize_t lfence_enabled_write(struct file *file,
        unsigned int enable;
 
        /* You have to disable IBRS first. */
-       if (ibrs_inuse) {
-               pr_warn("IBRS is enabled. Ignoring request to change lfence_enabled state.");
+       if (ibrs_inuse || retpoline_enabled()) {
+               pr_warn("%s is enabled. Ignoring request to change lfence_enabled state.\n",
+                       ibrs_inuse ? "IBRS" : "retpoline");
                return -EINVAL;
        }
 
@@ -184,6 +193,8 @@ static ssize_t lfence_enabled_write(struct file *file,
        else
                clear_lfence_disabled();
 
+       refresh_set_spectre_v2_enabled();
+
        mutex_unlock(&spec_ctrl_mutex);
        return count;
 }