| From 99862be42d1c774e140c07d5da941e15059710c7 Mon Sep 17 00:00:00 2001 |
| From: Daniel Sneddon <daniel.sneddon@linux.intel.com> |
| Date: Tue, 1 Aug 2023 16:36:25 +0200 |
| Subject: x86/speculation: Add Gather Data Sampling mitigation |
| |
| From: Daniel Sneddon <daniel.sneddon@linux.intel.com> |
| |
| commit 8974eb588283b7d44a7c91fa09fcbaf380339f3a upstream |
| |
| 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> |
| Signed-off-by: Daniel Sneddon <daniel.sneddon@linux.intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| Documentation/ABI/testing/sysfs-devices-system-cpu | 13 - |
| Documentation/admin-guide/hw-vuln/gather_data_sampling.rst | 99 +++++++++ |
| Documentation/admin-guide/hw-vuln/index.rst | 1 |
| Documentation/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 |
| |
| --- a/Documentation/ABI/testing/sysfs-devices-system-cpu |
| +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu |
| @@ -513,17 +513,18 @@ Description: information about CPUs hete |
| 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 |
| --- /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. |
| --- 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 |
| l1d_flush.rst |
| processor_mmio_stale_data.rst |
| cross-thread-rsb.rst |
| + gather_data_sampling.rst |
| --- a/Documentation/admin-guide/kernel-parameters.txt |
| +++ b/Documentation/admin-guide/kernel-parameters.txt |
| @@ -1593,6 +1593,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. |
| @@ -3228,24 +3242,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 |
| --- a/arch/x86/include/asm/cpufeatures.h |
| +++ b/arch/x86/include/asm/cpufeatures.h |
| @@ -464,5 +464,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 */ |
| --- a/arch/x86/include/asm/msr-index.h |
| +++ b/arch/x86/include/asm/msr-index.h |
| @@ -158,6 +158,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 |
| @@ -181,6 +190,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 |
| --- a/arch/x86/kernel/cpu/bugs.c |
| +++ b/arch/x86/kernel/cpu/bugs.c |
| @@ -46,6 +46,7 @@ static void __init taa_select_mitigation |
| 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(); |
| } |
| |
| /* |
| @@ -645,6 +647,120 @@ static int __init l1d_flush_parse_cmdlin |
| 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 |
| |
| enum spectre_v1_mitigation { |
| @@ -2356,6 +2472,11 @@ static ssize_t retbleed_show_state(char |
| return sprintf(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) |
| { |
| @@ -2405,6 +2526,9 @@ static ssize_t cpu_show_common(struct de |
| case X86_BUG_RETBLEED: |
| return retbleed_show_state(buf); |
| |
| + case X86_BUG_GDS: |
| + return gds_show_state(buf); |
| + |
| default: |
| break; |
| } |
| @@ -2469,4 +2593,9 @@ ssize_t cpu_show_retbleed(struct device |
| { |
| 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 |
| --- a/arch/x86/kernel/cpu/common.c |
| +++ b/arch/x86/kernel/cpu/common.c |
| @@ -1241,6 +1241,8 @@ static const __initconst struct x86_cpu_ |
| #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), |
| @@ -1253,19 +1255,21 @@ static const struct x86_cpu_id cpu_vuln_ |
| 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), |
| @@ -1394,6 +1398,16 @@ static void __init cpu_set_bug_bits(stru |
| 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; |
| |
| @@ -1957,6 +1971,8 @@ void identify_secondary_cpu(struct cpuin |
| 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(); |
| } |
| --- 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); |
| |
| --- a/drivers/base/cpu.c |
| +++ b/drivers/base/cpu.c |
| @@ -577,6 +577,12 @@ ssize_t __weak cpu_show_retbleed(struct |
| 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, |
| 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_vulner |
| &dev_attr_srbds.attr, |
| &dev_attr_mmio_stale_data.attr, |
| &dev_attr_retbleed.attr, |
| + &dev_attr_gather_data_sampling.attr, |
| NULL |
| }; |
| |