From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from userp2130.oracle.com ([156.151.31.86]) by Galois.linutronix.de with esmtps (TLS1.2:RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1f9Llm-0004AD-VB for speck@linutronix.de; Fri, 20 Apr 2018 04:27:27 +0200 Received: from pps.filterd (userp2130.oracle.com [127.0.0.1]) by userp2130.oracle.com (8.16.0.22/8.16.0.22) with SMTP id w3K2QLMX068515 for ; Fri, 20 Apr 2018 02:27:20 GMT Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp2130.oracle.com with ESMTP id 2hdrxp2kb2-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 20 Apr 2018 02:27:20 +0000 Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0022.oracle.com (8.14.4/8.14.4) with ESMTP id w3K2RJGp008964 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 20 Apr 2018 02:27:19 GMT Received: from abhmp0015.oracle.com (abhmp0015.oracle.com [141.146.116.21]) by userv0122.oracle.com (8.14.4/8.14.4) with ESMTP id w3K2RIDu026705 for ; Fri, 20 Apr 2018 02:27:18 GMT Message-Id: <20180420022613.203909041@localhost.localdomain> Date: Thu, 19 Apr 2018 22:25:46 -0400 From: konrad.wilk@oracle.com Subject: [MODERATED] [patch 06/11] [PATCH v2 06/10] Linux Patch #6 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit To: speck@linutronix.de List-ID: 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 --- 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: , 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 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