All of lore.kernel.org
 help / color / mirror / Atom feed
* [MODERATED] [patch 2/8] [PATCH v1.3.1 2/7] Linux Patch 2
@ 2018-04-13  2:26 konrad.wilk
  0 siblings, 0 replies; only message in thread
From: konrad.wilk @ 2018-04-13  2:26 UTC (permalink / raw)
  To: speck

mdd stands for "Memory Disambiguation Disable" and we have two knobs:

 nomdd
 mdd=[off,auto,userspace,boot]

(We couldn't use 'md' as that is used by multipath).

Memory Disambiguation is a feature that contemporary processors
have - which is where store and load operations can run
in parallel (even for the same address). Eventually when the memory
is fetched with the data value will the store (and load) be fixed
up and the execution operations re-run through the CPU.

Thanks to the nature of this store-load-store operations can run
in parallel. The 'mdd' allows the OS to disable this optimization.

Some CPUs have a bug where a load may pass an older overlapping
store (speculatively of course).

By default this feature is enabled hence the parameters are:

 - auto - if possible will disable memory disambiguation at boot if CPU
           is vulnerable to speculation attacks using memory disambgiuation..
 - boot - disable memory disambiguation at boot.
 - userspace - disable memory disambiguation when entering userspace, but
   enable it in the kernel.
 - off - do not _disable_ memory disambiguation.

And as mentioned - some CPU may have memory dismabiguation that does
not lead to speculative vulnerabilities - and for those the 'auto'
will pick the right choice.

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
v3:
 - 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
---
 Documentation/admin-guide/kernel-parameters.txt | 11 +++
 arch/x86/include/asm/cpufeatures.h              |  1 +
 arch/x86/include/asm/nospec-branch.h            |  6 ++
 arch/x86/kernel/cpu/bugs.c                      | 93 ++++++++++++++++++++++++-
 arch/x86/kernel/cpu/intel.c                     |  1 +
 5 files changed, 111 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 1d1d53f85ddd..2c22ca7e90a6 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2173,6 +2173,15 @@
 	md=		[HW] RAID subsystems devices and level
 			See Documentation/admin-guide/md.rst.
 
+	mdd=		[X86] Control memory disambiguation disable mitigation.
+
+			auto - kernel detects whether your CPU model is
+			       vulnerable and picks the most appropiate way
+			userspace - disable memory disambiguation in userspace,
+                               and enable it in the kernel.
+			boot  - disable memory disambiguation all the time (default).
+			off  - do not control memory disambiguation (insecure)
+
 	mdacon=		[MDA]
 			Format: <first>,<last>
 			Specifies range of consoles to be captured by the MDA.
@@ -2647,6 +2656,8 @@
 			allow data leaks with this option, which is equivalent
 			to spectre_v2=off.
 
+	nomdd		[X86] Disable all mitigations for the memory disambiguation 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.
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 4393c10fcc6f..7490798a70e9 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) /* Intel 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 f928ad9b143f..2c098a3250eb 100644
--- a/arch/x86/include/asm/nospec-branch.h
+++ b/arch/x86/include/asm/nospec-branch.h
@@ -216,6 +216,12 @@ enum spectre_v2_mitigation {
 	SPECTRE_V2_RETPOLINE_AMD,
 	SPECTRE_V2_IBRS,
 };
+/* The MD mitigation variants */
+enum md_mitigation {
+	MD_NONE,
+	MD_BOOT_ON,
+	MD_KERNEL_ON,
+};
 
 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 79dfc80c4b9c..561cb228605a 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 md_select_mitigation(void);
 
 void __init check_bugs(void)
 {
@@ -40,6 +41,8 @@ void __init check_bugs(void)
 	/* Select the proper spectre mitigation before patching alternatives */
 	spectre_v2_select_mitigation();
 
+	md_select_mitigation();
+
 #ifdef CONFIG_X86_32
 	/*
 	 * Check whether we are able to run this kernel safely on SMP.
@@ -311,6 +314,94 @@ static void __init spectre_v2_select_mitigation(void)
 	}
 }
 
+#undef pr_fmt
+#define pr_fmt(fmt)     "MDD: " fmt
+
+static enum md_mitigation md_mode = MD_NONE;
+
+/* The kernel command line selection */
+enum md_mitigation_cmd {
+	MD_CMD_NONE,
+	MD_CMD_AUTO,
+	MD_CMD_BOOT_ON,
+	MD_CMD_KERNEL_ON,
+};
+
+static const char *md_strings[] = {
+	[MD_NONE]			= "Vulnerable",
+	[MD_BOOT_ON]			= "Mitigation: Memory disambiguation disabled at boot",
+	[MD_KERNEL_ON]			= "Mitigation: Memory disambiguation disabled in userspace",
+};
+
+static const struct {
+	const char *option;
+	enum md_mitigation_cmd cmd;
+} md_mitigation_options[] = {
+	{ "off",               MD_CMD_NONE },
+	{ "auto",              MD_CMD_AUTO },
+	{ "boot",              MD_CMD_BOOT_ON },
+	{ "userspace",         MD_CMD_KERNEL_ON },
+};
+
+static enum md_mitigation_cmd __init md_parse_cmdline(void)
+{
+	char arg[20];
+	int ret, i;
+	enum md_mitigation_cmd cmd = MD_CMD_AUTO;
+
+	if (cmdline_find_option_bool(boot_command_line, "nomdd"))
+		return MD_CMD_NONE;
+	else {
+		ret = cmdline_find_option(boot_command_line, "mdd", arg, sizeof(arg));
+		if (ret < 0)
+			return MD_CMD_AUTO;
+
+		for (i = 0; i < ARRAY_SIZE(md_mitigation_options); i++) {
+			if (!match_option(arg, ret, md_mitigation_options[i].option))
+				continue;
+			cmd = md_mitigation_options[i].cmd;
+			break;
+		}
+
+		if (i >= ARRAY_SIZE(md_mitigation_options)) {
+			pr_err("unknown option (%s). Switching to AUTO select\n", arg);
+			return MD_CMD_AUTO;
+		}
+	}
+
+	return cmd;
+}
+
+static void __init md_select_mitigation(void)
+{
+	enum md_mitigation_cmd cmd = md_parse_cmdline();
+	enum md_mitigation mode = MD_NONE;
+
+	if (!boot_cpu_has_bug(X86_BUG_CPU_MD) &&
+	    (cmd == MD_CMD_NONE || cmd == MD_CMD_AUTO))
+		return;
+
+	switch (cmd) {
+	case MD_CMD_AUTO:
+	case MD_CMD_BOOT_ON:
+		mode = MD_BOOT_ON;
+		break;
+	case MD_CMD_KERNEL_ON:
+		mode = MD_KERNEL_ON;
+		break;
+	case MD_CMD_NONE:
+		break;
+	}
+
+	if (!boot_cpu_has(X86_FEATURE_MDD))
+		return;
+
+	md_mode = mode;
+	pr_info("%s\n", md_strings[mode]);
+
+	if (mode == MD_NONE)
+		setup_clear_cpu_cap(X86_FEATURE_MDD);
+}
 #undef pr_fmt
 
 #ifdef CONFIG_SYSFS
@@ -346,6 +437,6 @@ ssize_t cpu_show_md(struct device *dev, struct device_attribute *attr, char *buf
 	if (!boot_cpu_has_bug(X86_BUG_CPU_MD))
 		return sprintf(buf, "Not affected\n");
 
-	return sprintf(buf, "Vulnerable\n");
+	return sprintf(buf, "%s\n", md_strings[md_mode]);
 }
 #endif
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] only message in thread

only message in thread, other threads:[~2018-04-18 14:15 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-13  2:26 [MODERATED] [patch 2/8] [PATCH v1.3.1 2/7] Linux Patch 2 konrad.wilk

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.