aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2019-02-18 16:04:08 -0500
committerThomas Gleixner <tglx@linutronix.de>2019-03-06 15:52:14 -0500
commitbc1241700acd82ec69fde98c5763ce51086269f8 (patch)
tree4532204cd1990e79a806133e8e0b486853ab06e6
parent07f07f55a29cb705e221eda7894dd67ab81ef343 (diff)
x86/speculation/mds: Add mitigation control for MDS
Now that the mitigations are in place, add a command line parameter to control the mitigation, a mitigation selector function and a SMT update mechanism. This is the minimal straight forward initial implementation which just provides an always on/off mode. The command line parameter is: mds=[full|off] This is consistent with the existing mitigations for other speculative hardware vulnerabilities. The idle invocation is dynamically updated according to the SMT state of the system similar to the dynamic update of the STIBP mitigation. The idle mitigation is limited to CPUs which are only affected by MSBDS and not any other variant, because the other variants cannot be mitigated on SMT enabled systems. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Borislav Petkov <bp@suse.de> Reviewed-by: Jon Masters <jcm@redhat.com> Tested-by: Jon Masters <jcm@redhat.com>
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt22
-rw-r--r--arch/x86/include/asm/processor.h5
-rw-r--r--arch/x86/kernel/cpu/bugs.c70
3 files changed, 97 insertions, 0 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 858b6c0b9a15..dddb024eb523 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2356,6 +2356,28 @@
2356 Format: <first>,<last> 2356 Format: <first>,<last>
2357 Specifies range of consoles to be captured by the MDA. 2357 Specifies range of consoles to be captured by the MDA.
2358 2358
2359 mds= [X86,INTEL]
2360 Control mitigation for the Micro-architectural Data
2361 Sampling (MDS) vulnerability.
2362
2363 Certain CPUs are vulnerable to an exploit against CPU
2364 internal buffers which can forward information to a
2365 disclosure gadget under certain conditions.
2366
2367 In vulnerable processors, the speculatively
2368 forwarded data can be used in a cache side channel
2369 attack, to access data to which the attacker does
2370 not have direct access.
2371
2372 This parameter controls the MDS mitigation. The
2373 options are:
2374
2375 full - Enable MDS mitigation on vulnerable CPUs
2376 off - Unconditionally disable MDS mitigation
2377
2378 Not specifying this option is equivalent to
2379 mds=full.
2380
2359 mem=nn[KMG] [KNL,BOOT] Force usage of a specific amount of memory 2381 mem=nn[KMG] [KNL,BOOT] Force usage of a specific amount of memory
2360 Amount of memory to be used when the kernel is not able 2382 Amount of memory to be used when the kernel is not able
2361 to see the whole system memory or for test. 2383 to see the whole system memory or for test.
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 33051436c864..1f0295783325 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -992,4 +992,9 @@ enum l1tf_mitigations {
992 992
993extern enum l1tf_mitigations l1tf_mitigation; 993extern enum l1tf_mitigations l1tf_mitigation;
994 994
995enum mds_mitigations {
996 MDS_MITIGATION_OFF,
997 MDS_MITIGATION_FULL,
998};
999
995#endif /* _ASM_X86_PROCESSOR_H */ 1000#endif /* _ASM_X86_PROCESSOR_H */
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 916995167301..c7b29d200d27 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -37,6 +37,7 @@
37static void __init spectre_v2_select_mitigation(void); 37static void __init spectre_v2_select_mitigation(void);
38static void __init ssb_select_mitigation(void); 38static void __init ssb_select_mitigation(void);
39static void __init l1tf_select_mitigation(void); 39static void __init l1tf_select_mitigation(void);
40static void __init mds_select_mitigation(void);
40 41
41/* The base value of the SPEC_CTRL MSR that always has to be preserved. */ 42/* The base value of the SPEC_CTRL MSR that always has to be preserved. */
42u64 x86_spec_ctrl_base; 43u64 x86_spec_ctrl_base;
@@ -108,6 +109,8 @@ void __init check_bugs(void)
108 109
109 l1tf_select_mitigation(); 110 l1tf_select_mitigation();
110 111
112 mds_select_mitigation();
113
111#ifdef CONFIG_X86_32 114#ifdef CONFIG_X86_32
112 /* 115 /*
113 * Check whether we are able to run this kernel safely on SMP. 116 * Check whether we are able to run this kernel safely on SMP.
@@ -214,6 +217,50 @@ static void x86_amd_ssb_disable(void)
214} 217}
215 218
216#undef pr_fmt 219#undef pr_fmt
220#define pr_fmt(fmt) "MDS: " fmt
221
222/* Default mitigation for L1TF-affected CPUs */
223static enum mds_mitigations mds_mitigation __ro_after_init = MDS_MITIGATION_FULL;
224
225static const char * const mds_strings[] = {
226 [MDS_MITIGATION_OFF] = "Vulnerable",
227 [MDS_MITIGATION_FULL] = "Mitigation: Clear CPU buffers"
228};
229
230static void __init mds_select_mitigation(void)
231{
232 if (!boot_cpu_has_bug(X86_BUG_MDS)) {
233 mds_mitigation = MDS_MITIGATION_OFF;
234 return;
235 }
236
237 if (mds_mitigation == MDS_MITIGATION_FULL) {
238 if (boot_cpu_has(X86_FEATURE_MD_CLEAR))
239 static_branch_enable(&mds_user_clear);
240 else
241 mds_mitigation = MDS_MITIGATION_OFF;
242 }
243 pr_info("%s\n", mds_strings[mds_mitigation]);
244}
245
246static int __init mds_cmdline(char *str)
247{
248 if (!boot_cpu_has_bug(X86_BUG_MDS))
249 return 0;
250
251 if (!str)
252 return -EINVAL;
253
254 if (!strcmp(str, "off"))
255 mds_mitigation = MDS_MITIGATION_OFF;
256 else if (!strcmp(str, "full"))
257 mds_mitigation = MDS_MITIGATION_FULL;
258
259 return 0;
260}
261early_param("mds", mds_cmdline);
262
263#undef pr_fmt
217#define pr_fmt(fmt) "Spectre V2 : " fmt 264#define pr_fmt(fmt) "Spectre V2 : " fmt
218 265
219static enum spectre_v2_mitigation spectre_v2_enabled __ro_after_init = 266static enum spectre_v2_mitigation spectre_v2_enabled __ro_after_init =
@@ -617,6 +664,26 @@ static void update_indir_branch_cond(void)
617 static_branch_disable(&switch_to_cond_stibp); 664 static_branch_disable(&switch_to_cond_stibp);
618} 665}
619 666
667/* Update the static key controlling the MDS CPU buffer clear in idle */
668static void update_mds_branch_idle(void)
669{
670 /*
671 * Enable the idle clearing if SMT is active on CPUs which are
672 * affected only by MSBDS and not any other MDS variant.
673 *
674 * The other variants cannot be mitigated when SMT is enabled, so
675 * clearing the buffers on idle just to prevent the Store Buffer
676 * repartitioning leak would be a window dressing exercise.
677 */
678 if (!boot_cpu_has_bug(X86_BUG_MSBDS_ONLY))
679 return;
680
681 if (sched_smt_active())
682 static_branch_enable(&mds_idle_clear);
683 else
684 static_branch_disable(&mds_idle_clear);
685}
686
620void arch_smt_update(void) 687void arch_smt_update(void)
621{ 688{
622 /* Enhanced IBRS implies STIBP. No update required. */ 689 /* Enhanced IBRS implies STIBP. No update required. */
@@ -638,6 +705,9 @@ void arch_smt_update(void)
638 break; 705 break;
639 } 706 }
640 707
708 if (mds_mitigation == MDS_MITIGATION_FULL)
709 update_mds_branch_idle();
710
641 mutex_unlock(&spec_ctrl_mutex); 711 mutex_unlock(&spec_ctrl_mutex);
642} 712}
643 713