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 */
#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)
{
*/
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
#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>");
#include <asm/pat.h>
#include <asm/processor.h>
-
+#include <asm/spec_ctrl.h>
#include <asm/apic.h>
struct cpuid_bit {
#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"
#include <asm/kexec.h>
#include <asm/apic.h>
#include <asm/microcode.h>
+#include <asm/spec_ctrl.h>
#include "trace.h"
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>
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
*
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)
{
#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>