| From 49950a554e33dec5c44419622f3e68e51639c386 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| .../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); |
| } |
| |
| -- |
| 2.21.0 |
| |