summaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorDaniel Sneddon <daniel.sneddon@linux.intel.com>2023-07-12 19:43:12 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-08-08 19:49:19 +0200
commit91e24758cd8e53b030146fbe7ff5c2b258e60c66 (patch)
tree2d1bf5f71c4e682b41493f228c0e41924f977a55 /arch/x86
parente81494b7259b6b1ab81a9f9be3385b4aa99a7a59 (diff)
downloadlinux-stable-91e24758cd8e53b030146fbe7ff5c2b258e60c66.tar.gz
linux-stable-91e24758cd8e53b030146fbe7ff5c2b258e60c66.tar.bz2
linux-stable-91e24758cd8e53b030146fbe7ff5c2b258e60c66.zip
x86/speculation: Add force option to GDS mitigation
commit 553a5c03e90a6087e88f8ff878335ef0621536fb upstream The Gather Data Sampling (GDS) vulnerability allows malicious software to infer stale data previously stored in vector registers. This may include sensitive data such as cryptographic keys. GDS is mitigated in microcode, and systems with up-to-date microcode are protected by default. However, any affected system that is running with older microcode will still be vulnerable to GDS attacks. Since the gather instructions used by the attacker are part of the AVX2 and AVX512 extensions, disabling these extensions prevents gather instructions from being executed, thereby mitigating the system from GDS. Disabling AVX2 is sufficient, but we don't have the granularity to do this. The XCR0[2] disables AVX, with no option to just disable AVX2. Add a kernel parameter gather_data_sampling=force that will enable the microcode mitigation if available, otherwise it will disable AVX on affected systems. This option will be ignored if cmdline mitigations=off. This is a *big* hammer. It is known to break buggy userspace that uses incomplete, buggy AVX enumeration. Unfortunately, such userspace does exist in the wild: https://www.mail-archive.com/bug-coreutils@gnu.org/msg33046.html [ dhansen: add some more ominous warnings about disabling AVX ] Signed-off-by: Daniel Sneddon <daniel.sneddon@linux.intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Acked-by: Josh Poimboeuf <jpoimboe@kernel.org> Signed-off-by: Daniel Sneddon <daniel.sneddon@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/cpu/bugs.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 43bcaa76f754..e30319d44dbc 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -607,6 +607,7 @@ early_param("srbds", srbds_parse_cmdline);
enum gds_mitigations {
GDS_MITIGATION_OFF,
GDS_MITIGATION_UCODE_NEEDED,
+ GDS_MITIGATION_FORCE,
GDS_MITIGATION_FULL,
GDS_MITIGATION_FULL_LOCKED,
GDS_MITIGATION_HYPERVISOR,
@@ -617,6 +618,7 @@ static enum gds_mitigations gds_mitigation __ro_after_init = GDS_MITIGATION_FULL
static const char * const gds_strings[] = {
[GDS_MITIGATION_OFF] = "Vulnerable",
[GDS_MITIGATION_UCODE_NEEDED] = "Vulnerable: No microcode",
+ [GDS_MITIGATION_FORCE] = "Mitigation: AVX disabled, no microcode",
[GDS_MITIGATION_FULL] = "Mitigation: Microcode",
[GDS_MITIGATION_FULL_LOCKED] = "Mitigation: Microcode (locked)",
[GDS_MITIGATION_HYPERVISOR] = "Unknown: Dependent on hypervisor status",
@@ -642,6 +644,7 @@ void update_gds_msr(void)
rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl);
mcu_ctrl &= ~GDS_MITG_DIS;
break;
+ case GDS_MITIGATION_FORCE:
case GDS_MITIGATION_UCODE_NEEDED:
case GDS_MITIGATION_HYPERVISOR:
return;
@@ -676,10 +679,23 @@ static void __init gds_select_mitigation(void)
/* No microcode */
if (!(x86_read_arch_cap_msr() & ARCH_CAP_GDS_CTRL)) {
- gds_mitigation = GDS_MITIGATION_UCODE_NEEDED;
+ if (gds_mitigation == GDS_MITIGATION_FORCE) {
+ /*
+ * This only needs to be done on the boot CPU so do it
+ * here rather than in update_gds_msr()
+ */
+ setup_clear_cpu_cap(X86_FEATURE_AVX);
+ pr_warn("Microcode update needed! Disabling AVX as mitigation.\n");
+ } else {
+ gds_mitigation = GDS_MITIGATION_UCODE_NEEDED;
+ }
goto out;
}
+ /* Microcode has mitigation, use it */
+ if (gds_mitigation == GDS_MITIGATION_FORCE)
+ gds_mitigation = GDS_MITIGATION_FULL;
+
rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl);
if (mcu_ctrl & GDS_MITG_LOCKED) {
if (gds_mitigation == GDS_MITIGATION_OFF)
@@ -710,6 +726,8 @@ static int __init gds_parse_cmdline(char *str)
if (!strcmp(str, "off"))
gds_mitigation = GDS_MITIGATION_OFF;
+ else if (!strcmp(str, "force"))
+ gds_mitigation = GDS_MITIGATION_FORCE;
return 0;
}