192 lines
5.9 KiB
Diff
192 lines
5.9 KiB
Diff
From 892ec2b2472857d93fb2b3d125a13d9df4400ce0 Mon Sep 17 00:00:00 2001
|
|
From: Thomas Gleixner <tglx@linutronix.de>
|
|
Date: Mon, 18 Feb 2019 22:04:08 +0100
|
|
Subject: [PATCH 13/30] x86/speculation/mds: Add mitigation control for MDS
|
|
|
|
commit bc1241700acd82ec69fde98c5763ce51086269f8 upstream
|
|
|
|
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>
|
|
---
|
|
.../admin-guide/kernel-parameters.txt | 22 ++++++
|
|
arch/x86/include/asm/processor.h | 5 ++
|
|
arch/x86/kernel/cpu/bugs.c | 70 +++++++++++++++++++
|
|
3 files changed, 97 insertions(+)
|
|
|
|
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
|
|
index 8b6567f7cb9b..a0ab4521d7c5 100644
|
|
--- a/Documentation/admin-guide/kernel-parameters.txt
|
|
+++ b/Documentation/admin-guide/kernel-parameters.txt
|
|
@@ -2319,6 +2319,28 @@
|
|
Format: <first>,<last>
|
|
Specifies range of consoles to be captured by the MDA.
|
|
|
|
+ mds= [X86,INTEL]
|
|
+ Control mitigation for the Micro-architectural Data
|
|
+ Sampling (MDS) vulnerability.
|
|
+
|
|
+ Certain CPUs are vulnerable to an exploit against CPU
|
|
+ internal buffers which can forward information to a
|
|
+ disclosure gadget under certain conditions.
|
|
+
|
|
+ In vulnerable processors, the speculatively
|
|
+ forwarded data can be used in a cache side channel
|
|
+ attack, to access data to which the attacker does
|
|
+ not have direct access.
|
|
+
|
|
+ This parameter controls the MDS mitigation. The
|
|
+ options are:
|
|
+
|
|
+ full - Enable MDS mitigation on vulnerable CPUs
|
|
+ off - Unconditionally disable MDS mitigation
|
|
+
|
|
+ Not specifying this option is equivalent to
|
|
+ mds=full.
|
|
+
|
|
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.
|
|
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
|
|
index d53c54b842da..5e9f953face0 100644
|
|
--- a/arch/x86/include/asm/processor.h
|
|
+++ b/arch/x86/include/asm/processor.h
|
|
@@ -997,4 +997,9 @@ enum l1tf_mitigations {
|
|
|
|
extern enum l1tf_mitigations l1tf_mitigation;
|
|
|
|
+enum mds_mitigations {
|
|
+ MDS_MITIGATION_OFF,
|
|
+ MDS_MITIGATION_FULL,
|
|
+};
|
|
+
|
|
#endif /* _ASM_X86_PROCESSOR_H */
|
|
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
|
|
index 428fe6590360..413a672f03a3 100644
|
|
--- a/arch/x86/kernel/cpu/bugs.c
|
|
+++ b/arch/x86/kernel/cpu/bugs.c
|
|
@@ -35,6 +35,7 @@
|
|
static void __init spectre_v2_select_mitigation(void);
|
|
static void __init ssb_select_mitigation(void);
|
|
static void __init l1tf_select_mitigation(void);
|
|
+static void __init mds_select_mitigation(void);
|
|
|
|
/* The base value of the SPEC_CTRL MSR that always has to be preserved. */
|
|
u64 x86_spec_ctrl_base;
|
|
@@ -106,6 +107,8 @@ void __init check_bugs(void)
|
|
|
|
l1tf_select_mitigation();
|
|
|
|
+ mds_select_mitigation();
|
|
+
|
|
#ifdef CONFIG_X86_32
|
|
/*
|
|
* Check whether we are able to run this kernel safely on SMP.
|
|
@@ -211,6 +214,50 @@ static void x86_amd_ssb_disable(void)
|
|
wrmsrl(MSR_AMD64_LS_CFG, msrval);
|
|
}
|
|
|
|
+#undef pr_fmt
|
|
+#define pr_fmt(fmt) "MDS: " fmt
|
|
+
|
|
+/* Default mitigation for L1TF-affected CPUs */
|
|
+static enum mds_mitigations mds_mitigation __ro_after_init = MDS_MITIGATION_FULL;
|
|
+
|
|
+static const char * const mds_strings[] = {
|
|
+ [MDS_MITIGATION_OFF] = "Vulnerable",
|
|
+ [MDS_MITIGATION_FULL] = "Mitigation: Clear CPU buffers"
|
|
+};
|
|
+
|
|
+static void __init mds_select_mitigation(void)
|
|
+{
|
|
+ if (!boot_cpu_has_bug(X86_BUG_MDS)) {
|
|
+ mds_mitigation = MDS_MITIGATION_OFF;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (mds_mitigation == MDS_MITIGATION_FULL) {
|
|
+ if (boot_cpu_has(X86_FEATURE_MD_CLEAR))
|
|
+ static_branch_enable(&mds_user_clear);
|
|
+ else
|
|
+ mds_mitigation = MDS_MITIGATION_OFF;
|
|
+ }
|
|
+ pr_info("%s\n", mds_strings[mds_mitigation]);
|
|
+}
|
|
+
|
|
+static int __init mds_cmdline(char *str)
|
|
+{
|
|
+ if (!boot_cpu_has_bug(X86_BUG_MDS))
|
|
+ return 0;
|
|
+
|
|
+ if (!str)
|
|
+ return -EINVAL;
|
|
+
|
|
+ if (!strcmp(str, "off"))
|
|
+ mds_mitigation = MDS_MITIGATION_OFF;
|
|
+ else if (!strcmp(str, "full"))
|
|
+ mds_mitigation = MDS_MITIGATION_FULL;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+early_param("mds", mds_cmdline);
|
|
+
|
|
#undef pr_fmt
|
|
#define pr_fmt(fmt) "Spectre V2 : " fmt
|
|
|
|
@@ -603,6 +650,26 @@ static void update_indir_branch_cond(void)
|
|
static_branch_disable(&switch_to_cond_stibp);
|
|
}
|
|
|
|
+/* Update the static key controlling the MDS CPU buffer clear in idle */
|
|
+static void update_mds_branch_idle(void)
|
|
+{
|
|
+ /*
|
|
+ * Enable the idle clearing if SMT is active on CPUs which are
|
|
+ * affected only by MSBDS and not any other MDS variant.
|
|
+ *
|
|
+ * The other variants cannot be mitigated when SMT is enabled, so
|
|
+ * clearing the buffers on idle just to prevent the Store Buffer
|
|
+ * repartitioning leak would be a window dressing exercise.
|
|
+ */
|
|
+ if (!boot_cpu_has_bug(X86_BUG_MSBDS_ONLY))
|
|
+ return;
|
|
+
|
|
+ if (sched_smt_active())
|
|
+ static_branch_enable(&mds_idle_clear);
|
|
+ else
|
|
+ static_branch_disable(&mds_idle_clear);
|
|
+}
|
|
+
|
|
void arch_smt_update(void)
|
|
{
|
|
/* Enhanced IBRS implies STIBP. No update required. */
|
|
@@ -623,6 +690,9 @@ void arch_smt_update(void)
|
|
break;
|
|
}
|
|
|
|
+ if (mds_mitigation == MDS_MITIGATION_FULL)
|
|
+ update_mds_branch_idle();
|
|
+
|
|
mutex_unlock(&spec_ctrl_mutex);
|
|
}
|
|
|