9dd7462461
by cherry-picking the relevant commits from launchpad/lunar [0]. (relevant commits are based on k.o/stable commits for this) minimally tested by booting my (ryzen) machine with this kernel and skimming through dmesg after boot. [0] git://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/lunar Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
596 lines
24 KiB
Diff
596 lines
24 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Daniel Sneddon <daniel.sneddon@linux.intel.com>
|
|
Date: Wed, 12 Jul 2023 19:43:11 -0700
|
|
Subject: [PATCH] x86/speculation: Add Gather Data Sampling mitigation
|
|
|
|
Gather Data Sampling (GDS) is a hardware vulnerability which allows
|
|
unprivileged speculative access to data which was previously stored in
|
|
vector registers.
|
|
|
|
Intel processors that support AVX2 and AVX512 have gather instructions
|
|
that fetch non-contiguous data elements from memory. On vulnerable
|
|
hardware, when a gather instruction is transiently executed and
|
|
encounters a fault, stale data from architectural or internal vector
|
|
registers may get transiently stored to the destination vector
|
|
register allowing an attacker to infer the stale data using typical
|
|
side channel techniques like cache timing attacks.
|
|
|
|
This mitigation is different from many earlier ones for two reasons.
|
|
First, it is enabled by default and a bit must be set to *DISABLE* it.
|
|
This is the opposite of normal mitigation polarity. This means GDS can
|
|
be mitigated simply by updating microcode and leaving the new control
|
|
bit alone.
|
|
|
|
Second, GDS has a "lock" bit. This lock bit is there because the
|
|
mitigation affects the hardware security features KeyLocker and SGX.
|
|
It needs to be enabled and *STAY* enabled for these features to be
|
|
mitigated against GDS.
|
|
|
|
The mitigation is enabled in the microcode by default. Disable it by
|
|
setting gather_data_sampling=off or by disabling all mitigations with
|
|
mitigations=off. The mitigation status can be checked by reading:
|
|
|
|
/sys/devices/system/cpu/vulnerabilities/gather_data_sampling
|
|
|
|
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>
|
|
|
|
(cherry picked from commit 8974eb588283b7d44a7c91fa09fcbaf380339f3a)
|
|
CVE-2022-40982
|
|
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
|
|
Acked-by: Roxana Nicolescu <roxana.nicolescu@canonical.com>
|
|
Acked-by: Stefan Bader <stefan.bader@canonical.com>
|
|
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
|
|
(cherry picked from commit a82fd9ff16b574fc42677c7b5f9e05b2f965d709)
|
|
Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
|
|
---
|
|
.../ABI/testing/sysfs-devices-system-cpu | 13 +-
|
|
.../hw-vuln/gather_data_sampling.rst | 99 ++++++++++++++
|
|
Documentation/admin-guide/hw-vuln/index.rst | 1 +
|
|
.../admin-guide/kernel-parameters.txt | 41 ++++--
|
|
arch/x86/include/asm/cpufeatures.h | 1 +
|
|
arch/x86/include/asm/msr-index.h | 11 ++
|
|
arch/x86/kernel/cpu/bugs.c | 129 ++++++++++++++++++
|
|
arch/x86/kernel/cpu/common.c | 34 +++--
|
|
arch/x86/kernel/cpu/cpu.h | 1 +
|
|
drivers/base/cpu.c | 8 ++
|
|
10 files changed, 310 insertions(+), 28 deletions(-)
|
|
create mode 100644 Documentation/admin-guide/hw-vuln/gather_data_sampling.rst
|
|
|
|
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
|
|
index f54867cadb0f..13c01b641dc7 100644
|
|
--- a/Documentation/ABI/testing/sysfs-devices-system-cpu
|
|
+++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
|
|
@@ -513,17 +513,18 @@ Description: information about CPUs heterogeneity.
|
|
cpu_capacity: capacity of cpuX.
|
|
|
|
What: /sys/devices/system/cpu/vulnerabilities
|
|
+ /sys/devices/system/cpu/vulnerabilities/gather_data_sampling
|
|
+ /sys/devices/system/cpu/vulnerabilities/itlb_multihit
|
|
+ /sys/devices/system/cpu/vulnerabilities/l1tf
|
|
+ /sys/devices/system/cpu/vulnerabilities/mds
|
|
/sys/devices/system/cpu/vulnerabilities/meltdown
|
|
+ /sys/devices/system/cpu/vulnerabilities/mmio_stale_data
|
|
+ /sys/devices/system/cpu/vulnerabilities/retbleed
|
|
+ /sys/devices/system/cpu/vulnerabilities/spec_store_bypass
|
|
/sys/devices/system/cpu/vulnerabilities/spectre_v1
|
|
/sys/devices/system/cpu/vulnerabilities/spectre_v2
|
|
- /sys/devices/system/cpu/vulnerabilities/spec_store_bypass
|
|
- /sys/devices/system/cpu/vulnerabilities/l1tf
|
|
- /sys/devices/system/cpu/vulnerabilities/mds
|
|
/sys/devices/system/cpu/vulnerabilities/srbds
|
|
/sys/devices/system/cpu/vulnerabilities/tsx_async_abort
|
|
- /sys/devices/system/cpu/vulnerabilities/itlb_multihit
|
|
- /sys/devices/system/cpu/vulnerabilities/mmio_stale_data
|
|
- /sys/devices/system/cpu/vulnerabilities/retbleed
|
|
Date: January 2018
|
|
Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org>
|
|
Description: Information about CPU vulnerabilities
|
|
diff --git a/Documentation/admin-guide/hw-vuln/gather_data_sampling.rst b/Documentation/admin-guide/hw-vuln/gather_data_sampling.rst
|
|
new file mode 100644
|
|
index 000000000000..74dab6af7fe1
|
|
--- /dev/null
|
|
+++ b/Documentation/admin-guide/hw-vuln/gather_data_sampling.rst
|
|
@@ -0,0 +1,99 @@
|
|
+.. SPDX-License-Identifier: GPL-2.0
|
|
+
|
|
+GDS - Gather Data Sampling
|
|
+==========================
|
|
+
|
|
+Gather Data Sampling is a hardware vulnerability which allows unprivileged
|
|
+speculative access to data which was previously stored in vector registers.
|
|
+
|
|
+Problem
|
|
+-------
|
|
+When a gather instruction performs loads from memory, different data elements
|
|
+are merged into the destination vector register. However, when a gather
|
|
+instruction that is transiently executed encounters a fault, stale data from
|
|
+architectural or internal vector registers may get transiently forwarded to the
|
|
+destination vector register instead. This will allow a malicious attacker to
|
|
+infer stale data using typical side channel techniques like cache timing
|
|
+attacks. GDS is a purely sampling-based attack.
|
|
+
|
|
+The attacker uses gather instructions to infer the stale vector register data.
|
|
+The victim does not need to do anything special other than use the vector
|
|
+registers. The victim does not need to use gather instructions to be
|
|
+vulnerable.
|
|
+
|
|
+Because the buffers are shared between Hyper-Threads cross Hyper-Thread attacks
|
|
+are possible.
|
|
+
|
|
+Attack scenarios
|
|
+----------------
|
|
+Without mitigation, GDS can infer stale data across virtually all
|
|
+permission boundaries:
|
|
+
|
|
+ Non-enclaves can infer SGX enclave data
|
|
+ Userspace can infer kernel data
|
|
+ Guests can infer data from hosts
|
|
+ Guest can infer guest from other guests
|
|
+ Users can infer data from other users
|
|
+
|
|
+Because of this, it is important to ensure that the mitigation stays enabled in
|
|
+lower-privilege contexts like guests and when running outside SGX enclaves.
|
|
+
|
|
+The hardware enforces the mitigation for SGX. Likewise, VMMs should ensure
|
|
+that guests are not allowed to disable the GDS mitigation. If a host erred and
|
|
+allowed this, a guest could theoretically disable GDS mitigation, mount an
|
|
+attack, and re-enable it.
|
|
+
|
|
+Mitigation mechanism
|
|
+--------------------
|
|
+This issue is mitigated in microcode. The microcode defines the following new
|
|
+bits:
|
|
+
|
|
+ ================================ === ============================
|
|
+ IA32_ARCH_CAPABILITIES[GDS_CTRL] R/O Enumerates GDS vulnerability
|
|
+ and mitigation support.
|
|
+ IA32_ARCH_CAPABILITIES[GDS_NO] R/O Processor is not vulnerable.
|
|
+ IA32_MCU_OPT_CTRL[GDS_MITG_DIS] R/W Disables the mitigation
|
|
+ 0 by default.
|
|
+ IA32_MCU_OPT_CTRL[GDS_MITG_LOCK] R/W Locks GDS_MITG_DIS=0. Writes
|
|
+ to GDS_MITG_DIS are ignored
|
|
+ Can't be cleared once set.
|
|
+ ================================ === ============================
|
|
+
|
|
+GDS can also be mitigated on systems that don't have updated microcode by
|
|
+disabling AVX. This can be done by setting "clearcpuid=avx" on the kernel
|
|
+command-line.
|
|
+
|
|
+Mitigation control on the kernel command line
|
|
+---------------------------------------------
|
|
+The mitigation can be disabled by setting "gather_data_sampling=off" or
|
|
+"mitigations=off" on the kernel command line. Not specifying either will
|
|
+default to the mitigation being enabled.
|
|
+
|
|
+GDS System Information
|
|
+------------------------
|
|
+The kernel provides vulnerability status information through sysfs. For
|
|
+GDS this can be accessed by the following sysfs file:
|
|
+
|
|
+/sys/devices/system/cpu/vulnerabilities/gather_data_sampling
|
|
+
|
|
+The possible values contained in this file are:
|
|
+
|
|
+ ============================== =============================================
|
|
+ Not affected Processor not vulnerable.
|
|
+ Vulnerable Processor vulnerable and mitigation disabled.
|
|
+ Vulnerable: No microcode Processor vulnerable and microcode is missing
|
|
+ mitigation.
|
|
+ Mitigation: Microcode Processor is vulnerable and mitigation is in
|
|
+ effect.
|
|
+ Mitigation: Microcode (locked) Processor is vulnerable and mitigation is in
|
|
+ effect and cannot be disabled.
|
|
+ Unknown: Dependent on
|
|
+ hypervisor status Running on a virtual guest processor that is
|
|
+ affected but with no way to know if host
|
|
+ processor is mitigated or vulnerable.
|
|
+ ============================== =============================================
|
|
+
|
|
+GDS Default mitigation
|
|
+----------------------
|
|
+The updated microcode will enable the mitigation by default. The kernel's
|
|
+default action is to leave the mitigation enabled.
|
|
diff --git a/Documentation/admin-guide/hw-vuln/index.rst b/Documentation/admin-guide/hw-vuln/index.rst
|
|
index e0614760a99e..436fac0bd9c3 100644
|
|
--- a/Documentation/admin-guide/hw-vuln/index.rst
|
|
+++ b/Documentation/admin-guide/hw-vuln/index.rst
|
|
@@ -19,3 +19,4 @@ are configurable at compile, boot or run time.
|
|
l1d_flush.rst
|
|
processor_mmio_stale_data.rst
|
|
cross-thread-rsb.rst
|
|
+ gather_data_sampling.rst
|
|
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
|
|
index c0d8867359bc..380e1e46ffa1 100644
|
|
--- a/Documentation/admin-guide/kernel-parameters.txt
|
|
+++ b/Documentation/admin-guide/kernel-parameters.txt
|
|
@@ -1610,6 +1610,20 @@
|
|
Format: off | on
|
|
default: on
|
|
|
|
+ gather_data_sampling=
|
|
+ [X86,INTEL] Control the Gather Data Sampling (GDS)
|
|
+ mitigation.
|
|
+
|
|
+ Gather Data Sampling is a hardware vulnerability which
|
|
+ allows unprivileged speculative access to data which was
|
|
+ previously stored in vector registers.
|
|
+
|
|
+ This issue is mitigated by default in updated microcode.
|
|
+ The mitigation may have a performance impact but can be
|
|
+ disabled.
|
|
+
|
|
+ off: Disable GDS mitigation.
|
|
+
|
|
gcov_persist= [GCOV] When non-zero (default), profiling data for
|
|
kernel modules is saved and remains accessible via
|
|
debugfs, even when the module is unloaded/reloaded.
|
|
@@ -3245,24 +3259,25 @@
|
|
Disable all optional CPU mitigations. This
|
|
improves system performance, but it may also
|
|
expose users to several CPU vulnerabilities.
|
|
- Equivalent to: nopti [X86,PPC]
|
|
- if nokaslr then kpti=0 [ARM64]
|
|
- nospectre_v1 [X86,PPC]
|
|
- nobp=0 [S390]
|
|
- nospectre_v2 [X86,PPC,S390,ARM64]
|
|
- spectre_v2_user=off [X86]
|
|
- spec_store_bypass_disable=off [X86,PPC]
|
|
- ssbd=force-off [ARM64]
|
|
- nospectre_bhb [ARM64]
|
|
+ Equivalent to: if nokaslr then kpti=0 [ARM64]
|
|
+ gather_data_sampling=off [X86]
|
|
+ kvm.nx_huge_pages=off [X86]
|
|
l1tf=off [X86]
|
|
mds=off [X86]
|
|
- tsx_async_abort=off [X86]
|
|
- kvm.nx_huge_pages=off [X86]
|
|
- srbds=off [X86,INTEL]
|
|
+ mmio_stale_data=off [X86]
|
|
no_entry_flush [PPC]
|
|
no_uaccess_flush [PPC]
|
|
- mmio_stale_data=off [X86]
|
|
+ nobp=0 [S390]
|
|
+ nopti [X86,PPC]
|
|
+ nospectre_bhb [ARM64]
|
|
+ nospectre_v1 [X86,PPC]
|
|
+ nospectre_v2 [X86,PPC,S390,ARM64]
|
|
retbleed=off [X86]
|
|
+ spec_store_bypass_disable=off [X86,PPC]
|
|
+ spectre_v2_user=off [X86]
|
|
+ srbds=off [X86,INTEL]
|
|
+ ssbd=force-off [ARM64]
|
|
+ tsx_async_abort=off [X86]
|
|
|
|
Exceptions:
|
|
This does not have any effect on
|
|
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
|
|
index 8f39c46197b8..93f232eb9786 100644
|
|
--- a/arch/x86/include/asm/cpufeatures.h
|
|
+++ b/arch/x86/include/asm/cpufeatures.h
|
|
@@ -467,5 +467,6 @@
|
|
#define X86_BUG_RETBLEED X86_BUG(27) /* CPU is affected by RETBleed */
|
|
#define X86_BUG_EIBRS_PBRSB X86_BUG(28) /* EIBRS is vulnerable to Post Barrier RSB Predictions */
|
|
#define X86_BUG_SMT_RSB X86_BUG(29) /* CPU is vulnerable to Cross-Thread Return Address Predictions */
|
|
+#define X86_BUG_GDS X86_BUG(30) /* CPU is affected by Gather Data Sampling */
|
|
|
|
#endif /* _ASM_X86_CPUFEATURES_H */
|
|
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
|
|
index 52a09dbc2c26..b030a03ca8d6 100644
|
|
--- a/arch/x86/include/asm/msr-index.h
|
|
+++ b/arch/x86/include/asm/msr-index.h
|
|
@@ -153,6 +153,15 @@
|
|
* Not susceptible to Post-Barrier
|
|
* Return Stack Buffer Predictions.
|
|
*/
|
|
+#define ARCH_CAP_GDS_CTRL BIT(25) /*
|
|
+ * CPU is vulnerable to Gather
|
|
+ * Data Sampling (GDS) and
|
|
+ * has controls for mitigation.
|
|
+ */
|
|
+#define ARCH_CAP_GDS_NO BIT(26) /*
|
|
+ * CPU is not vulnerable to Gather
|
|
+ * Data Sampling (GDS).
|
|
+ */
|
|
|
|
#define ARCH_CAP_XAPIC_DISABLE BIT(21) /*
|
|
* IA32_XAPIC_DISABLE_STATUS MSR
|
|
@@ -176,6 +185,8 @@
|
|
#define RNGDS_MITG_DIS BIT(0) /* SRBDS support */
|
|
#define RTM_ALLOW BIT(1) /* TSX development mode */
|
|
#define FB_CLEAR_DIS BIT(3) /* CPU Fill buffer clear disable */
|
|
+#define GDS_MITG_DIS BIT(4) /* Disable GDS mitigation */
|
|
+#define GDS_MITG_LOCKED BIT(5) /* GDS mitigation locked */
|
|
|
|
#define MSR_IA32_SYSENTER_CS 0x00000174
|
|
#define MSR_IA32_SYSENTER_ESP 0x00000175
|
|
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
|
|
index edb670b77294..a1c1c8e4995c 100644
|
|
--- a/arch/x86/kernel/cpu/bugs.c
|
|
+++ b/arch/x86/kernel/cpu/bugs.c
|
|
@@ -46,6 +46,7 @@ static void __init taa_select_mitigation(void);
|
|
static void __init mmio_select_mitigation(void);
|
|
static void __init srbds_select_mitigation(void);
|
|
static void __init l1d_flush_select_mitigation(void);
|
|
+static void __init gds_select_mitigation(void);
|
|
|
|
/* The base value of the SPEC_CTRL MSR without task-specific bits set */
|
|
u64 x86_spec_ctrl_base;
|
|
@@ -159,6 +160,7 @@ void __init cpu_select_mitigations(void)
|
|
md_clear_select_mitigation();
|
|
srbds_select_mitigation();
|
|
l1d_flush_select_mitigation();
|
|
+ gds_select_mitigation();
|
|
}
|
|
|
|
/*
|
|
@@ -644,6 +646,120 @@ static int __init l1d_flush_parse_cmdline(char *str)
|
|
}
|
|
early_param("l1d_flush", l1d_flush_parse_cmdline);
|
|
|
|
+#undef pr_fmt
|
|
+#define pr_fmt(fmt) "GDS: " fmt
|
|
+
|
|
+enum gds_mitigations {
|
|
+ GDS_MITIGATION_OFF,
|
|
+ GDS_MITIGATION_UCODE_NEEDED,
|
|
+ GDS_MITIGATION_FULL,
|
|
+ GDS_MITIGATION_FULL_LOCKED,
|
|
+ GDS_MITIGATION_HYPERVISOR,
|
|
+};
|
|
+
|
|
+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_FULL] = "Mitigation: Microcode",
|
|
+ [GDS_MITIGATION_FULL_LOCKED] = "Mitigation: Microcode (locked)",
|
|
+ [GDS_MITIGATION_HYPERVISOR] = "Unknown: Dependent on hypervisor status",
|
|
+};
|
|
+
|
|
+void update_gds_msr(void)
|
|
+{
|
|
+ u64 mcu_ctrl_after;
|
|
+ u64 mcu_ctrl;
|
|
+
|
|
+ switch (gds_mitigation) {
|
|
+ case GDS_MITIGATION_OFF:
|
|
+ rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl);
|
|
+ mcu_ctrl |= GDS_MITG_DIS;
|
|
+ break;
|
|
+ case GDS_MITIGATION_FULL_LOCKED:
|
|
+ /*
|
|
+ * The LOCKED state comes from the boot CPU. APs might not have
|
|
+ * the same state. Make sure the mitigation is enabled on all
|
|
+ * CPUs.
|
|
+ */
|
|
+ case GDS_MITIGATION_FULL:
|
|
+ rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl);
|
|
+ mcu_ctrl &= ~GDS_MITG_DIS;
|
|
+ break;
|
|
+ case GDS_MITIGATION_UCODE_NEEDED:
|
|
+ case GDS_MITIGATION_HYPERVISOR:
|
|
+ return;
|
|
+ };
|
|
+
|
|
+ wrmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl);
|
|
+
|
|
+ /*
|
|
+ * Check to make sure that the WRMSR value was not ignored. Writes to
|
|
+ * GDS_MITG_DIS will be ignored if this processor is locked but the boot
|
|
+ * processor was not.
|
|
+ */
|
|
+ rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl_after);
|
|
+ WARN_ON_ONCE(mcu_ctrl != mcu_ctrl_after);
|
|
+}
|
|
+
|
|
+static void __init gds_select_mitigation(void)
|
|
+{
|
|
+ u64 mcu_ctrl;
|
|
+
|
|
+ if (!boot_cpu_has_bug(X86_BUG_GDS))
|
|
+ return;
|
|
+
|
|
+ if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) {
|
|
+ gds_mitigation = GDS_MITIGATION_HYPERVISOR;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (cpu_mitigations_off())
|
|
+ gds_mitigation = GDS_MITIGATION_OFF;
|
|
+ /* Will verify below that mitigation _can_ be disabled */
|
|
+
|
|
+ /* No microcode */
|
|
+ if (!(x86_read_arch_cap_msr() & ARCH_CAP_GDS_CTRL)) {
|
|
+ gds_mitigation = GDS_MITIGATION_UCODE_NEEDED;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl);
|
|
+ if (mcu_ctrl & GDS_MITG_LOCKED) {
|
|
+ if (gds_mitigation == GDS_MITIGATION_OFF)
|
|
+ pr_warn("Mitigation locked. Disable failed.\n");
|
|
+
|
|
+ /*
|
|
+ * The mitigation is selected from the boot CPU. All other CPUs
|
|
+ * _should_ have the same state. If the boot CPU isn't locked
|
|
+ * but others are then update_gds_msr() will WARN() of the state
|
|
+ * mismatch. If the boot CPU is locked update_gds_msr() will
|
|
+ * ensure the other CPUs have the mitigation enabled.
|
|
+ */
|
|
+ gds_mitigation = GDS_MITIGATION_FULL_LOCKED;
|
|
+ }
|
|
+
|
|
+ update_gds_msr();
|
|
+out:
|
|
+ pr_info("%s\n", gds_strings[gds_mitigation]);
|
|
+}
|
|
+
|
|
+static int __init gds_parse_cmdline(char *str)
|
|
+{
|
|
+ if (!str)
|
|
+ return -EINVAL;
|
|
+
|
|
+ if (!boot_cpu_has_bug(X86_BUG_GDS))
|
|
+ return 0;
|
|
+
|
|
+ if (!strcmp(str, "off"))
|
|
+ gds_mitigation = GDS_MITIGATION_OFF;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+early_param("gather_data_sampling", gds_parse_cmdline);
|
|
+
|
|
#undef pr_fmt
|
|
#define pr_fmt(fmt) "Spectre V1 : " fmt
|
|
|
|
@@ -2385,6 +2501,11 @@ static ssize_t retbleed_show_state(char *buf)
|
|
return sysfs_emit(buf, "%s\n", retbleed_strings[retbleed_mitigation]);
|
|
}
|
|
|
|
+static ssize_t gds_show_state(char *buf)
|
|
+{
|
|
+ return sysfs_emit(buf, "%s\n", gds_strings[gds_mitigation]);
|
|
+}
|
|
+
|
|
static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr,
|
|
char *buf, unsigned int bug)
|
|
{
|
|
@@ -2434,6 +2555,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
|
|
case X86_BUG_RETBLEED:
|
|
return retbleed_show_state(buf);
|
|
|
|
+ case X86_BUG_GDS:
|
|
+ return gds_show_state(buf);
|
|
+
|
|
default:
|
|
break;
|
|
}
|
|
@@ -2498,4 +2622,9 @@ ssize_t cpu_show_retbleed(struct device *dev, struct device_attribute *attr, cha
|
|
{
|
|
return cpu_show_common(dev, attr, buf, X86_BUG_RETBLEED);
|
|
}
|
|
+
|
|
+ssize_t cpu_show_gds(struct device *dev, struct device_attribute *attr, char *buf)
|
|
+{
|
|
+ return cpu_show_common(dev, attr, buf, X86_BUG_GDS);
|
|
+}
|
|
#endif
|
|
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
|
|
index 9b53d1cb424d..d950fb5ac0b4 100644
|
|
--- a/arch/x86/kernel/cpu/common.c
|
|
+++ b/arch/x86/kernel/cpu/common.c
|
|
@@ -1262,6 +1262,8 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
|
|
#define RETBLEED BIT(3)
|
|
/* CPU is affected by SMT (cross-thread) return predictions */
|
|
#define SMT_RSB BIT(4)
|
|
+/* CPU is affected by GDS */
|
|
+#define GDS BIT(5)
|
|
|
|
static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
|
|
VULNBL_INTEL_STEPPINGS(IVYBRIDGE, X86_STEPPING_ANY, SRBDS),
|
|
@@ -1274,19 +1276,21 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
|
|
VULNBL_INTEL_STEPPINGS(BROADWELL_X, X86_STEPPING_ANY, MMIO),
|
|
VULNBL_INTEL_STEPPINGS(BROADWELL, X86_STEPPING_ANY, SRBDS),
|
|
VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED),
|
|
- VULNBL_INTEL_STEPPINGS(SKYLAKE_X, X86_STEPPING_ANY, MMIO | RETBLEED),
|
|
+ VULNBL_INTEL_STEPPINGS(SKYLAKE_X, X86_STEPPING_ANY, MMIO | RETBLEED | GDS),
|
|
VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED),
|
|
- VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED),
|
|
- VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED),
|
|
+ VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED | GDS),
|
|
+ VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED | GDS),
|
|
VULNBL_INTEL_STEPPINGS(CANNONLAKE_L, X86_STEPPING_ANY, RETBLEED),
|
|
- VULNBL_INTEL_STEPPINGS(ICELAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED),
|
|
- VULNBL_INTEL_STEPPINGS(ICELAKE_D, X86_STEPPING_ANY, MMIO),
|
|
- VULNBL_INTEL_STEPPINGS(ICELAKE_X, X86_STEPPING_ANY, MMIO),
|
|
- VULNBL_INTEL_STEPPINGS(COMETLAKE, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED),
|
|
+ VULNBL_INTEL_STEPPINGS(ICELAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS),
|
|
+ VULNBL_INTEL_STEPPINGS(ICELAKE_D, X86_STEPPING_ANY, MMIO | GDS),
|
|
+ VULNBL_INTEL_STEPPINGS(ICELAKE_X, X86_STEPPING_ANY, MMIO | GDS),
|
|
+ VULNBL_INTEL_STEPPINGS(COMETLAKE, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS),
|
|
VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPINGS(0x0, 0x0), MMIO | RETBLEED),
|
|
- VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED),
|
|
+ VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS),
|
|
+ VULNBL_INTEL_STEPPINGS(TIGERLAKE_L, X86_STEPPING_ANY, GDS),
|
|
+ VULNBL_INTEL_STEPPINGS(TIGERLAKE, X86_STEPPING_ANY, GDS),
|
|
VULNBL_INTEL_STEPPINGS(LAKEFIELD, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED),
|
|
- VULNBL_INTEL_STEPPINGS(ROCKETLAKE, X86_STEPPING_ANY, MMIO | RETBLEED),
|
|
+ VULNBL_INTEL_STEPPINGS(ROCKETLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS),
|
|
VULNBL_INTEL_STEPPINGS(ATOM_TREMONT, X86_STEPPING_ANY, MMIO | MMIO_SBDS),
|
|
VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_D, X86_STEPPING_ANY, MMIO),
|
|
VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS),
|
|
@@ -1415,6 +1419,16 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
|
|
if (cpu_matches(cpu_vuln_blacklist, SMT_RSB))
|
|
setup_force_cpu_bug(X86_BUG_SMT_RSB);
|
|
|
|
+ /*
|
|
+ * Check if CPU is vulnerable to GDS. If running in a virtual machine on
|
|
+ * an affected processor, the VMM may have disabled the use of GATHER by
|
|
+ * disabling AVX2. The only way to do this in HW is to clear XCR0[2],
|
|
+ * which means that AVX will be disabled.
|
|
+ */
|
|
+ if (cpu_matches(cpu_vuln_blacklist, GDS) && !(ia32_cap & ARCH_CAP_GDS_NO) &&
|
|
+ boot_cpu_has(X86_FEATURE_AVX))
|
|
+ setup_force_cpu_bug(X86_BUG_GDS);
|
|
+
|
|
if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
|
|
return;
|
|
|
|
@@ -1977,6 +1991,8 @@ void identify_secondary_cpu(struct cpuinfo_x86 *c)
|
|
validate_apic_and_package_id(c);
|
|
x86_spec_ctrl_setup_ap();
|
|
update_srbds_msr();
|
|
+ if (boot_cpu_has_bug(X86_BUG_GDS))
|
|
+ update_gds_msr();
|
|
|
|
tsx_ap_init();
|
|
}
|
|
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h
|
|
index 61dbb9b216e6..d9aeb335002d 100644
|
|
--- a/arch/x86/kernel/cpu/cpu.h
|
|
+++ b/arch/x86/kernel/cpu/cpu.h
|
|
@@ -83,6 +83,7 @@ void cpu_select_mitigations(void);
|
|
|
|
extern void x86_spec_ctrl_setup_ap(void);
|
|
extern void update_srbds_msr(void);
|
|
+extern void update_gds_msr(void);
|
|
|
|
extern u64 x86_read_arch_cap_msr(void);
|
|
|
|
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
|
|
index 7af8e33735a3..cc6cf06ce88e 100644
|
|
--- a/drivers/base/cpu.c
|
|
+++ b/drivers/base/cpu.c
|
|
@@ -577,6 +577,12 @@ ssize_t __weak cpu_show_retbleed(struct device *dev,
|
|
return sysfs_emit(buf, "Not affected\n");
|
|
}
|
|
|
|
+ssize_t __weak cpu_show_gds(struct device *dev,
|
|
+ struct device_attribute *attr, char *buf)
|
|
+{
|
|
+ return sysfs_emit(buf, "Not affected\n");
|
|
+}
|
|
+
|
|
static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL);
|
|
static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL);
|
|
static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL);
|
|
@@ -588,6 +594,7 @@ static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL);
|
|
static DEVICE_ATTR(srbds, 0444, cpu_show_srbds, NULL);
|
|
static DEVICE_ATTR(mmio_stale_data, 0444, cpu_show_mmio_stale_data, NULL);
|
|
static DEVICE_ATTR(retbleed, 0444, cpu_show_retbleed, NULL);
|
|
+static DEVICE_ATTR(gather_data_sampling, 0444, cpu_show_gds, NULL);
|
|
|
|
static struct attribute *cpu_root_vulnerabilities_attrs[] = {
|
|
&dev_attr_meltdown.attr,
|
|
@@ -601,6 +608,7 @@ static struct attribute *cpu_root_vulnerabilities_attrs[] = {
|
|
&dev_attr_srbds.attr,
|
|
&dev_attr_mmio_stale_data.attr,
|
|
&dev_attr_retbleed.attr,
|
|
+ &dev_attr_gather_data_sampling.attr,
|
|
NULL
|
|
};
|
|
|