]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
x86: Clean up IBRS functionality resident in common code
authorKanth Ghatraju <kanth.ghatraju@oracle.com>
Tue, 16 Jan 2018 21:03:57 +0000 (16:03 -0500)
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Wed, 17 Jan 2018 20:29:11 +0000 (15:29 -0500)
The IBRS and IBPB code and defines are resident in common code.
This patch moves them to x86 specific locations.

The patch also adds the command line options:
spectre_v2={on|off|auto}
nospectre_v2

on: unconditionally enable
off: unconditionally disable, no_spectre_v2, noibrs + noibpb
auto: default, on

Existing noibrs and noibpb will print a deprecated message

Orabug: 27353383
Signed-off-by: Kanth Ghatraju <kanth.ghatraju@oracle.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Acked-by: John Haxby <john.haxby@oracle.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
arch/x86/include/asm/spec_ctrl.h
arch/x86/kernel/cpu/bugs_64.c
arch/x86/kernel/cpu/microcode/core.c
arch/x86/kernel/cpu/scattered.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
include/linux/smp.h
kernel/smp.c
kernel/sysctl.c

index e62ea4685a1c20cba0a23f23d34fffaed59571d0..85fe1105f9e16984e8fa2f52b6979e036e0c3a39 100644 (file)
@@ -210,5 +210,107 @@ enum {
        IBRS_ENABLED_USER,
        IBRS_MAX = IBRS_ENABLED_USER,
 };
+
+/* indicate usage of IBRS to control execution speculation */
+extern int use_ibrs;
+extern u32 sysctl_ibrs_enabled;
+extern struct mutex spec_ctrl_mutex;
+
+#define ibrs_supported         (use_ibrs & SPEC_CTRL_IBRS_SUPPORTED)
+#define ibrs_disabled          (use_ibrs & SPEC_CTRL_IBRS_ADMIN_DISABLED)
+
+#define ibrs_inuse             (check_ibrs_inuse())
+
+static inline void set_ibrs_inuse(void)
+{
+       if (ibrs_supported)
+               use_ibrs |= SPEC_CTRL_IBRS_INUSE;
+}
+
+static inline void clear_ibrs_inuse(void)
+{
+       use_ibrs &= ~SPEC_CTRL_IBRS_INUSE;
+}
+
+static inline int check_ibrs_inuse(void)
+{
+       if (use_ibrs & SPEC_CTRL_IBRS_INUSE)
+               return 1;
+       else
+               /* rmb to prevent wrong speculation for security */
+               rmb();
+       return 0;
+}
+
+static inline void set_ibrs_supported(void)
+{
+       use_ibrs |= SPEC_CTRL_IBRS_SUPPORTED;
+       if (!ibrs_disabled)
+               set_ibrs_inuse();
+}
+
+static inline void set_ibrs_disabled(void)
+{
+       use_ibrs |= SPEC_CTRL_IBRS_ADMIN_DISABLED;
+       if (check_ibrs_inuse())
+               clear_ibrs_inuse();
+}
+
+static inline void clear_ibrs_disabled(void)
+{
+       use_ibrs &= ~SPEC_CTRL_IBRS_ADMIN_DISABLED;
+       set_ibrs_inuse();
+}
+
+/* indicate usage of IBPB to control execution speculation */
+extern int use_ibpb;
+extern u32 sysctl_ibpb_enabled;
+
+#define ibpb_supported         (use_ibpb & 0x2)
+#define ibpb_disabled          (use_ibpb & 0x4)
+
+#define ibpb_inuse             (check_ibpb_inuse())
+
+static inline void set_ibpb_inuse(void)
+{
+       if (ibpb_supported)
+               use_ibpb |= 0x1;
+}
+
+static inline void clear_ibpb_inuse(void)
+{
+       use_ibpb &= ~0x1;
+}
+
+static inline int check_ibpb_inuse(void)
+{
+       if (use_ibpb & 0x1)
+               return 1;
+       else
+               /* rmb to prevent wrong speculation for security */
+               rmb();
+       return 0;
+}
+
+static inline void set_ibpb_supported(void)
+{
+       use_ibpb |= 0x2;
+       if (!ibpb_disabled)
+               set_ibpb_inuse();
+}
+
+static inline void set_ibpb_disabled(void)
+{
+       use_ibpb |= 0x4;
+       if (check_ibpb_inuse())
+               clear_ibpb_inuse();
+}
+
+static inline void clear_ibpb_disabled(void)
+{
+       use_ibpb &= ~0x4;
+       set_ibpb_inuse();
+}
+
 #endif /* __ASSEMBLY__ */
 #endif /* _ASM_X86_SPEC_CTRL_H */
index 90bce302496392b57891f8c88f0922426e5bd7fe..0d471c66786024cb014ef7017b41bf24f1854119 100644 (file)
 #include <asm/processor.h>
 #include <asm/mtrr.h>
 #include <asm/cacheflush.h>
+#include <asm/spec_ctrl.h>
+#include <asm/cmdline.h>
+
+/*
+ * use IBRS
+ * bit 0 = indicate if ibrs is currently in use
+ * bit 1 = indicate if system supports ibrs
+ * bit 2 = indicate if admin disables ibrs
+ */
+int use_ibrs;
+EXPORT_SYMBOL(use_ibrs);
+
+/*
+ * use IBRS
+ * bit 0 = indicate if ibpb is currently in use
+ * bit 1 = indicate if system supports ibpb
+ * bit 2 = indicate if admin disables ibpb
+ */
+int use_ibpb;
+EXPORT_SYMBOL(use_ibpb);
+
+/* mutex to serialize IBRS & IBPB control changes */
+DEFINE_MUTEX(spec_ctrl_mutex);
+EXPORT_SYMBOL(spec_ctrl_mutex);
+
+static void __init spectre_v2_parse_cmdline(void);
 
 void __init check_bugs(void)
 {
@@ -30,6 +56,67 @@ void __init check_bugs(void)
         */
        if (!direct_gbpages)
                set_memory_4k((unsigned long)__va(0), 1);
+
+       spectre_v2_parse_cmdline();
+}
+
+static inline bool match_option(const char *arg, int arglen, const char *opt)
+{
+       int len = strlen(opt);
+
+       return len == arglen && !strncmp(arg, opt, len);
+}
+
+static void spectre_v2_usage_error(const char *str)
+{
+       pr_warn("%s arguments for option spectre_v2. "
+                   "Usage spectre_v2={on|off|auto}\n", str);
+}
+
+static void __init spectre_v2_parse_cmdline(void)
+{
+       char arg[20];
+       int ret;
+
+       if (cmdline_find_option_bool(boot_command_line, "noibrs")) {
+               pr_warn("Deprecated command option noibrs. "
+                       "Use nospectre_v2 instead.\n");
+               set_ibrs_disabled();
+       }
+
+       if (cmdline_find_option_bool(boot_command_line, "noibpb")) {
+               pr_warn("Deprecated command option noibpb. "
+                       "Use nospectre_v2 instead.\n");
+               set_ibpb_disabled();
+       }
+
+       if (cmdline_find_option_bool(boot_command_line, "nospectre_v2"))
+               goto disable;
+
+       ret = cmdline_find_option(boot_command_line, "spectre_v2", arg,
+           sizeof(arg));
+
+       if (ret > 0) {
+
+               if (match_option(arg, ret, "off"))
+                       goto disable;
+
+               if (match_option(arg, ret, "on") ||
+                       match_option(arg, ret, "auto")) {
+                       if (!(ibrs_supported || ibpb_supported))
+                               pr_warn("Spectre_v2 mitigation unsupported\n");
+               } else {
+                       spectre_v2_usage_error("Invalid");
+               }
+       } else {
+               spectre_v2_usage_error("Missing");
+       }
+
+       return;
+
+disable:
+       set_ibrs_disabled();
+       set_ibpb_disabled();
 }
 
 #ifdef CONFIG_SYSFS
index 44fe1cfee5fed6a4b9b1968b4fc5c9e9eb53fc0e..6b7a843db4549b0b9cba709e7974736be8c6bd1c 100644 (file)
@@ -88,6 +88,7 @@
 #include <asm/processor.h>
 #include <asm/cpu_device_id.h>
 #include <asm/perf_event.h>
+#include <asm/spec_ctrl.h>
 
 MODULE_DESCRIPTION("Microcode Update Driver");
 MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
index 887580fdbc0f209edaa73e7a96745060c0a8a596..af1e5c8d7910c189450dd08cf329120d89181a1a 100644 (file)
@@ -6,7 +6,7 @@
 
 #include <asm/pat.h>
 #include <asm/processor.h>
-
+#include <asm/spec_ctrl.h>
 #include <asm/apic.h>
 
 struct cpuid_bit {
index fa2cb89c5403044f3d1d2b871bd5c24e4ca8f008..0ec051b7707382145093436caa2de3e97bab33f8 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/desc.h>
 #include <asm/debugreg.h>
 #include <asm/kvm_para.h>
+#include <asm/spec_ctrl.h>
 
 #include <asm/virtext.h>
 #include "trace.h"
index 8aa10dd99157b42da49d17b6a44ea7a9e2978ac0..aa9bc4f0a426b9bd672eec312c9b7d1482e7c883 100644 (file)
@@ -48,6 +48,7 @@
 #include <asm/kexec.h>
 #include <asm/apic.h>
 #include <asm/microcode.h>
+#include <asm/spec_ctrl.h>
 
 #include "trace.h"
 
index ed927292713bf60ecdace31520b9925971675c7e..c4414074bd88e2ae1b042cb477440f54b2f241dd 100644 (file)
@@ -50,94 +50,6 @@ void on_each_cpu_cond(bool (*cond_func)(int cpu, void *info),
 
 int smp_call_function_single_async(int cpu, struct call_single_data *csd);
 
-#ifdef CONFIG_X86
-#include <asm/spec_ctrl.h>
-/* indicate usage of IBRS to control execution speculation */
-extern int use_ibrs;
-extern u32 sysctl_ibrs_enabled;
-extern struct mutex spec_ctrl_mutex;
-#define ibrs_supported         (use_ibrs & SPEC_CTRL_IBRS_SUPPORTED)
-#define ibrs_disabled          (use_ibrs & SPEC_CTRL_IBRS_ADMIN_DISABLED)
-static inline void set_ibrs_inuse(void)
-{
-       if (ibrs_supported)
-               use_ibrs |= SPEC_CTRL_IBRS_INUSE;
-}
-static inline void clear_ibrs_inuse(void)
-{
-       use_ibrs &= ~SPEC_CTRL_IBRS_INUSE;
-}
-static inline int check_ibrs_inuse(void)
-{
-       if (use_ibrs & SPEC_CTRL_IBRS_INUSE)
-               return 1;
-       else
-               /* rmb to prevent wrong speculation for security */
-               rmb();
-       return 0;
-}
-static inline void set_ibrs_supported(void)
-{
-       use_ibrs |= SPEC_CTRL_IBRS_SUPPORTED;
-       if (!ibrs_disabled)
-               set_ibrs_inuse();
-}
-static inline void set_ibrs_disabled(void)
-{
-       use_ibrs |= SPEC_CTRL_IBRS_ADMIN_DISABLED;
-       if (check_ibrs_inuse())
-               clear_ibrs_inuse();
-}
-static inline void clear_ibrs_disabled(void)
-{
-       use_ibrs &= ~SPEC_CTRL_IBRS_ADMIN_DISABLED;
-       set_ibrs_inuse();
-}
-#define ibrs_inuse             (check_ibrs_inuse())
-
-/* indicate usage of IBPB to control execution speculation */
-extern int use_ibpb;
-extern u32 sysctl_ibpb_enabled;
-#define ibpb_supported         (use_ibpb & 0x2)
-#define ibpb_disabled          (use_ibpb & 0x4)
-static inline void set_ibpb_inuse(void)
-{
-       if (ibpb_supported)
-               use_ibpb |= 0x1;
-}
-static inline void clear_ibpb_inuse(void)
-{
-       use_ibpb &= ~0x1;
-}
-static inline int check_ibpb_inuse(void)
-{
-       if (use_ibpb & 0x1)
-               return 1;
-       else
-               /* rmb to prevent wrong speculation for security */
-               rmb();
-       return 0;
-}
-static inline void set_ibpb_supported(void)
-{
-       use_ibpb |= 0x2;
-       if (!ibpb_disabled)
-               set_ibpb_inuse();
-}
-static inline void set_ibpb_disabled(void)
-{
-       use_ibpb |= 0x4;
-       if (check_ibpb_inuse())
-               clear_ibpb_inuse();
-}
-static inline void clear_ibpb_disabled(void)
-{
-       use_ibpb &= ~0x4;
-       set_ibpb_inuse();
-}
-#define ibpb_inuse             (check_ibpb_inuse())
-#endif
-
 #ifdef CONFIG_SMP
 
 #include <linux/preempt.h>
index d71ad2deb8057c4d9e63357f53406cd0c3f6ced9..e0fc52ca8d63d88c9b12c8e4aa3d997e6ff648ea 100644 (file)
@@ -499,29 +499,6 @@ EXPORT_SYMBOL(smp_call_function);
 unsigned int setup_max_cpus = NR_CPUS;
 EXPORT_SYMBOL(setup_max_cpus);
 
-/*
- * use IBRS
- * bit 0 = indicate if ibrs is currently in use
- * bit 1 = indicate if system supports ibrs
- * bit 2 = indicate if admin disables ibrs
-*/
-
-int use_ibrs;
-EXPORT_SYMBOL(use_ibrs);
-
-/*
- * use IBRS
- * bit 0 = indicate if ibpb is currently in use
- * bit 1 = indicate if system supports ibpb
- * bit 2 = indicate if admin disables ibpb
-*/
-int use_ibpb;
-EXPORT_SYMBOL(use_ibpb);
-
-/* mutex to serialize IBRS & IBPB control changes */
-DEFINE_MUTEX(spec_ctrl_mutex);
-EXPORT_SYMBOL(spec_ctrl_mutex);
-
 /*
  * Setup routine for controlling SMP activation
  *
@@ -545,25 +522,6 @@ static int __init nosmp(char *str)
 
 early_param("nosmp", nosmp);
 
-static int __init noibrs(char *str)
-{
-       set_ibrs_disabled();
-
-       return 0;
-}
-
-early_param("noibrs", noibrs);
-
-static int __init noibpb(char *str)
-{
-       set_ibpb_disabled();
-
-       return 0;
-}
-
-early_param("noibpb", noibpb);
-
-
 /* this is hard limit */
 static int __init nrcpus(char *str)
 {
index 5428d939b693308a6ac4453021802220d476d211..af526f11deb7990c188ba1bce3d2f447c1197a8d 100644 (file)
@@ -76,6 +76,7 @@
 #include <asm/nmi.h>
 #include <asm/stacktrace.h>
 #include <asm/io.h>
+#include <asm/spec_ctrl.h>
 #endif
 #ifdef CONFIG_SPARC
 #include <asm/setup.h>