1. At boot time
noibrs kernel boot parameter will disable IBRS usage
noibpb kernel boot parameter will disable IBPB usage
Otherwise if the above parameters are not specified, the system
will enable ibrs and ibpb usage if the cpu supports it.
Orabug:
27344012
CVE: CVE-2017-5715
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
[*Scaffolding*:This backport lacks a lot. It is only put it on so that the
later patches compiled _and_ can be tested to run. It is meant to be removed
once the full set of patches are all good. Aka scaffolding.]
Reviewed-by: John Haxby <john.haxby@oracle.com>
Signed-off-by: Kirtikar Kashyap <kirtikar.kashyap@oracle.com>
noexec=on: enable non-executable mappings (default)
noexec=off: disable non-executable mappings
+ noibrs [X86]
+ Don't use indirect branch restricted speculation (IBRS)
+ feature when running in secure environment,
+ to avoid performance overhead.
+
+ noibpb [X86]
+ Don't use indirect branch prediction barrier (IBPB)
+ feature when running in secure environment,
+ to avoid performance overhead.
+
nosmap [X86]
Disable SMAP (Supervisor Mode Access Prevention)
even if it is supported by processor.
#ifdef __ASSEMBLY__
+.extern use_ibrs
+
#define __ASM_ENABLE_IBRS \
pushq %rax; \
pushq %rcx; \
}
}
- if (boot_cpu_has(X86_FEATURE_SPEC_CTRL))
+ if (boot_cpu_has(X86_FEATURE_SPEC_CTRL)) {
printk_once(KERN_INFO "FEATURE SPEC_CTRL Present\n");
+ set_ibrs_supported();
+ }
else
printk_once(KERN_INFO "FEATURE SPEC_CTRL Not Present\n");
}
int smp_call_function_single_async(int cpu, struct call_single_data *csd);
+#ifdef CONFIG_X86
+/* indicate usage of IBRS to control execution speculation */
+extern int use_ibrs;
+extern u32 sysctl_ibrs_enabled;
+#define ibrs_supported (use_ibrs & 0x2)
+#define ibrs_disabled (use_ibrs & 0x4)
+static inline void set_ibrs_inuse(void)
+{
+ if (ibrs_supported)
+ use_ibrs |= 0x1;
+}
+static inline void clear_ibrs_inuse(void)
+{
+ use_ibrs &= ~0x1;
+}
+static inline int check_ibrs_inuse(void)
+{
+ if (use_ibrs & 0x1)
+ return 1;
+ else
+ /* rmb to prevent wrong speculation for security */
+ rmb();
+ return 0;
+}
+static inline void set_ibrs_supported(void)
+{
+ use_ibrs |= 0x2;
+ if (!ibrs_disabled)
+ set_ibrs_inuse();
+}
+static inline void set_ibrs_disabled(void)
+{
+ use_ibrs |= 0x4;
+ if (check_ibrs_inuse())
+ clear_ibrs_inuse();
+}
+static inline void clear_ibrs_disabled(void)
+{
+ use_ibrs &= ~0x4;
+ 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);
/*
* 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)
{