All of lore.kernel.org
 help / color / mirror / Atom feed
* [MODERATED] [patch 06/11] [PATCH v2 06/10] Linux Patch #6
@ 2018-04-20  2:25 konrad.wilk
  2018-04-20  5:28 ` [MODERATED] " Jon Masters
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: konrad.wilk @ 2018-04-20  2:25 UTC (permalink / raw)
  To: speck

mdd stands for "Memory Disambiguation Disable". It is used to disable
a common industry performance optimization known as "Speculative
Store Bypass" in which loads from addresses to which a recent store
has occurred may (speculatively) see an older value. Intel refers
to this feature as "Memory Disambiguation", which is part of their
"Smart Memory Access" capability in Haswell and later processors.

Some processors have an implementation bug that enables a cache
side-channel attack against such speculatively read values. An
attacker can create exploit code that allows them to read memory
outside of a sandbox environment (for example, malicious JavaScript
in a web page), or to perform more complex attacks against code
running within the same privilege level, e.g. via the stack.

We provide two sets of knobs. The first are x86 specific:

 nomdd
 mdd=[off,auto,on]

We also support cross-architecture versions of these:

 nossbd
 ssbd=[off,auto,on]

By default Memory Disambiguation is enabled hence the parameters are:

 - auto - if possible will disable Memory Disambiguation (MD) at boot
	  if CPU is vulnerable to speculation attacks against MD
 - on   - disable Memory Disambiguation
 - off  - enable Memory Disambiguation

And as mentioned - some CPUs may have an Memory Disambiguation
implementation which is not vulnerable to speculation attack.
For those, the 'auto' (default) option will pick the right choice.

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>

---
v1.3:
 - Wrong array was used when figuring mdd_v4= arguments
 - If broken microcode found, also disable MD feature.
 - s/mdd_v4/mdd/
 - s/kernel/userpsace/
 - Fix up the commit description
v1.4:
 - Incorporate various feedback and suggestions from Jon Masters
 - Change mdd parameters to allow only big hammer on/off for now
 - Introduce "ssbd" industry standard term for cross-architecture
 - Use mdd_ and MDD_ prefixes to clearly spell out that "enable"
   means we are actually disabling a CPU processor feature (MD)
v2:
 - s/mdd/ssb/ in the x86 code to match with the 'ssb' part

Conflicts:
	arch/x86/kernel/cpu/bugs.c
---
 Documentation/admin-guide/kernel-parameters.txt |  42 ++++++++++
 arch/x86/include/asm/cpufeatures.h              |   1 +
 arch/x86/include/asm/nospec-branch.h            |   6 ++
 arch/x86/kernel/cpu/bugs.c                      | 101 ++++++++++++++++++++++++
 arch/x86/kernel/cpu/intel.c                     |   1 +
 5 files changed, 151 insertions(+)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 1d1d53f85ddd..7a8f7680234e 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2177,6 +2177,22 @@
 			Format: <first>,<last>
 			Specifies range of consoles to be captured by the MDA.
 
+	mdd=		[X86] Control Memory Disambiguation (MD) Disable mitigation
+			(Speculative Store Bypass) vulnerability.
+
+			Certain CPUs are vulnerable to an exploit against a
+			performance optimization known as "Memory Disambiguation"
+			or by the industry term "Speculative Store Bypass". This
+			parameter controls whether the MD optimization is used.
+
+			on - unconditionally disable Memory Disambiguation
+			off - unconditionally enable Memory Disambiguation
+			auto - kernel detects whether your CPU model contains a
+			       vulnerable implementation of Memory Disambiguation
+			       and picks the most appropriate mitigation available
+
+			Not specifying this option is equivalent to mdd=auto.
+
 	mem=nn[KMG]	[KNL,BOOT] Force usage of a specific amount of memory
 			Amount of memory to be used when the kernel is not able
 			to see the whole system memory or for test.
@@ -2639,6 +2655,8 @@
 
 	nohugeiomap	[KNL,x86] Disable kernel huge I/O mappings.
 
+	nomdd		[X86] Disable all mitigations for the Memory Disambiguation vulnerability
+
 	nosmt		[KNL,S390] Disable symmetric multithreading (SMT).
 			Equivalent to smt=1.
 
@@ -2647,6 +2665,8 @@
 			allow data leaks with this option, which is equivalent
 			to spectre_v2=off.
 
+	nossbd		[HW] Disable all mitigations for the Speculative Store Bypass vulnerability
+
 	noxsave		[BUGS=X86] Disables x86 extended register state save
 			and restore using xsave. The kernel will fallback to
 			enabling legacy floating-point and sse state.
@@ -4019,6 +4039,28 @@
 			expediting.  Set to zero to disable automatic
 			expediting.
 
+	ssbd		[HW] Control Speculative Store Bypass (SSB) Disable mitigation
+			(Speculative Store Bypass vulnerability)
+
+			Certain CPUs are vulnerable to an exploit against a
+			a common industry wide performance optimization known
+			as "Speculative Store Bypass" in which recent stores
+			to the same memory location may not be observed by
+			later loads. This can be used in cache side channel
+			attacks to read memory to which the attacker does
+			not directly have access (e.g. sandboxed code).
+
+			This parameter controls whether the Speculative Store
+			Bypass optimization is used.
+
+			on - unconditionally disable Speculative Store Bypass
+			off - unconditionally enable Speculative Store Bypass
+			auto - kernel detects whether your CPU model contains a
+			       vulnerable implementation of Speculative Store
+			       Bypass and picks the most appropriate mitigation
+
+			Not specifying this option is equivalent to ssbd=auto
+
 	stack_guard_gap=	[MM]
 			override the default stack gap protection. The value
 			is in page units and it defines how many pages prior
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index f0ea33c95dc1..418ba6aee0d5 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -333,6 +333,7 @@
 #define X86_FEATURE_SPEC_CTRL		(18*32+26) /* "" Speculation Control (IBRS + IBPB) */
 #define X86_FEATURE_INTEL_STIBP		(18*32+27) /* "" Single Thread Indirect Branch Predictors */
 #define X86_FEATURE_ARCH_CAPABILITIES	(18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */
+#define X86_FEATURE_MDD			(18*32+31) /* Memory Disambiguation Disable */
 
 /*
  * BUG word(s)
diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
index f8cc8e0c0c9c..96e5d61e035a 100644
--- a/arch/x86/include/asm/nospec-branch.h
+++ b/arch/x86/include/asm/nospec-branch.h
@@ -224,6 +224,12 @@ extern u64 set_spec_ctrl(u64 val);
 extern u64 clear_spec_ctrl(u64 val);
 extern bool need_spec_ctrl_acc(void);
 
+/* The Speculative Store Bypass disable variants */
+enum ssb_mitigation {
+	SSB_NONE,
+	SSB_DISABLE,
+};
+
 extern char __indirect_thunk_start[];
 extern char __indirect_thunk_end[];
 
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 2838802346fc..b8513a93f4b8 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -27,6 +27,7 @@
 #include <asm/intel-family.h>
 
 static void __init spectre_v2_select_mitigation(void);
+static void __init ssb_select_mitigation(void);
 static void __init spec_ctrl_save_msr(void);
 
 void __init check_bugs(void)
@@ -43,6 +44,12 @@ void __init check_bugs(void)
 	/* Select the proper spectre mitigation before patching alternatives */
 	spectre_v2_select_mitigation();
 
+	/*
+	 * Select the proper mitigation for any exposure to Memory Disambiguation
+	 * vulnerability (otherwise known as Speculative Store Bypass)
+	 */
+	ssb_select_mitigation();
+
 #ifdef CONFIG_X86_32
 	/*
 	 * Check whether we are able to run this kernel safely on SMP.
@@ -344,6 +351,97 @@ static void __init spectre_v2_select_mitigation(void)
 	}
 }
 
+#undef pr_fmt
+#define pr_fmt(fmt)	"SSB: " fmt
+
+static enum ssb_mitigation ssb_mode = SSB_NONE;
+
+/* The kernel command line selection */
+enum ssb_mitigation_cmd {
+	SSB_CMD_NONE,
+	SSB_CMD_AUTO,
+	SSB_CMD_ON,
+};
+
+static const char *ssb_strings[] = {
+	[SSB_NONE]			= "Vulnerable",
+	[SSB_DISABLE]			= "Mitigation: Memory Disambiguation (MD) disabled"
+};
+
+static const struct {
+	const char *option;
+	enum ssb_mitigation_cmd cmd;
+} ssb_mitigation_options[] = {
+	{ "auto",		SSB_CMD_AUTO },	/* Platform decides */
+	{ "on",			SSB_CMD_ON },	/* Disable SSB */
+	{ "off",		SSB_CMD_NONE },	/* Don't touch SSB */
+};
+
+static enum ssb_mitigation_cmd __init ssb_parse_cmdline(void)
+{
+	char arg[20];
+	int ret, i;
+	enum ssb_mitigation_cmd cmd = SSB_CMD_AUTO;
+
+	/*
+	 * On Intel it is exposed in CPUID as Memory Disambiguation Disable
+	 * bit.
+	 */
+	if (!boot_cpu_has(X86_FEATURE_MDD))
+                return SSB_CMD_NONE;
+
+	if (cmdline_find_option_bool(boot_command_line, "nomdd") ||
+	    cmdline_find_option_bool(boot_command_line, "nossbd"))
+		return SSB_CMD_NONE;
+	else {
+		ret = cmdline_find_option(boot_command_line, "mdd", arg, sizeof(arg));
+		if (ret < 0)
+			ret = cmdline_find_option(boot_command_line, "ssbd", arg, sizeof(arg));
+		if (ret < 0)
+			return SSB_CMD_AUTO;
+
+		for (i = 0; i < ARRAY_SIZE(ssb_mitigation_options); i++) {
+			if (!match_option(arg, ret, ssb_mitigation_options[i].option))
+				continue;
+
+			cmd = ssb_mitigation_options[i].cmd;
+			break;
+		}
+
+		if (i >= ARRAY_SIZE(ssb_mitigation_options)) {
+			pr_err("unknown option (%s). Switching to AUTO select\n", arg);
+			return SSB_CMD_AUTO;
+		}
+	}
+
+	return cmd;
+}
+
+static void __init ssb_select_mitigation(void)
+{
+	enum ssb_mitigation_cmd cmd = ssb_parse_cmdline();
+	enum ssb_mitigation mode = SSB_NONE;
+
+	if (!boot_cpu_has_bug(X86_BUG_CPU_SSB) &&
+	    (cmd == SSB_CMD_NONE || cmd == SSB_CMD_AUTO))
+		return;
+
+	switch (cmd) {
+	case SSB_CMD_AUTO:
+	case SSB_CMD_ON:
+		mode = SSB_DISABLE;
+		break;
+	case SSB_CMD_NONE:
+		break;
+	}
+
+	ssb_mode = mode;
+	pr_info("%s\n", ssb_strings[mode]);
+
+	if (mode == SSB_NONE)
+		setup_clear_cpu_cap(X86_FEATURE_MDD);
+}
+
 #undef pr_fmt
 
 #ifdef CONFIG_SYSFS
@@ -370,6 +468,9 @@ ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr,
 			       boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "",
 			       spectre_v2_module_string());
 
+	case X86_BUG_CPU_SSB:
+		return sprintf(buf, "%s\n", ssb_strings[ssb_mode]);
+
 	default:
 		break;
 	}
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index c3af167d0a70..16ee38d8977a 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -189,6 +189,7 @@ static void early_init_intel(struct cpuinfo_x86 *c)
 		setup_clear_cpu_cap(X86_FEATURE_STIBP);
 		setup_clear_cpu_cap(X86_FEATURE_SPEC_CTRL);
 		setup_clear_cpu_cap(X86_FEATURE_INTEL_STIBP);
+		setup_clear_cpu_cap(X86_FEATURE_MDD);
 	}
 
 	/*
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-04-21  9:21 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-04-20  2:25 [MODERATED] [patch 06/11] [PATCH v2 06/10] Linux Patch #6 konrad.wilk
2018-04-20  5:28 ` [MODERATED] " Jon Masters
2018-04-20 11:21 ` Peter Zijlstra
2018-04-20 15:33   ` Jon Masters
2018-04-20 15:58     ` Konrad Rzeszutek Wilk
2018-04-20 16:11       ` Jon Masters
2018-04-20 17:25 ` Borislav Petkov
2018-04-21  9:21 ` Borislav Petkov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.