Skip to content

Commit c66ebe0

Browse files
Daniel Sneddongregkh
authored andcommitted
x86/speculation: Add Gather Data Sampling mitigation
commit 8974eb5 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 <[email protected]> Signed-off-by: Dave Hansen <[email protected]> Acked-by: Josh Poimboeuf <[email protected]> Signed-off-by: Daniel Sneddon <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent f25ad76 commit c66ebe0

File tree

10 files changed

+310
-28
lines changed

10 files changed

+310
-28
lines changed

Documentation/ABI/testing/sysfs-devices-system-cpu

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -513,17 +513,18 @@ Description: information about CPUs heterogeneity.
513513
cpu_capacity: capacity of cpuX.
514514

515515
What: /sys/devices/system/cpu/vulnerabilities
516+
/sys/devices/system/cpu/vulnerabilities/gather_data_sampling
517+
/sys/devices/system/cpu/vulnerabilities/itlb_multihit
518+
/sys/devices/system/cpu/vulnerabilities/l1tf
519+
/sys/devices/system/cpu/vulnerabilities/mds
516520
/sys/devices/system/cpu/vulnerabilities/meltdown
521+
/sys/devices/system/cpu/vulnerabilities/mmio_stale_data
522+
/sys/devices/system/cpu/vulnerabilities/retbleed
523+
/sys/devices/system/cpu/vulnerabilities/spec_store_bypass
517524
/sys/devices/system/cpu/vulnerabilities/spectre_v1
518525
/sys/devices/system/cpu/vulnerabilities/spectre_v2
519-
/sys/devices/system/cpu/vulnerabilities/spec_store_bypass
520-
/sys/devices/system/cpu/vulnerabilities/l1tf
521-
/sys/devices/system/cpu/vulnerabilities/mds
522526
/sys/devices/system/cpu/vulnerabilities/srbds
523527
/sys/devices/system/cpu/vulnerabilities/tsx_async_abort
524-
/sys/devices/system/cpu/vulnerabilities/itlb_multihit
525-
/sys/devices/system/cpu/vulnerabilities/mmio_stale_data
526-
/sys/devices/system/cpu/vulnerabilities/retbleed
527528
Date: January 2018
528529
Contact: Linux kernel mailing list <[email protected]>
529530
Description: Information about CPU vulnerabilities
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
3+
GDS - Gather Data Sampling
4+
==========================
5+
6+
Gather Data Sampling is a hardware vulnerability which allows unprivileged
7+
speculative access to data which was previously stored in vector registers.
8+
9+
Problem
10+
-------
11+
When a gather instruction performs loads from memory, different data elements
12+
are merged into the destination vector register. However, when a gather
13+
instruction that is transiently executed encounters a fault, stale data from
14+
architectural or internal vector registers may get transiently forwarded to the
15+
destination vector register instead. This will allow a malicious attacker to
16+
infer stale data using typical side channel techniques like cache timing
17+
attacks. GDS is a purely sampling-based attack.
18+
19+
The attacker uses gather instructions to infer the stale vector register data.
20+
The victim does not need to do anything special other than use the vector
21+
registers. The victim does not need to use gather instructions to be
22+
vulnerable.
23+
24+
Because the buffers are shared between Hyper-Threads cross Hyper-Thread attacks
25+
are possible.
26+
27+
Attack scenarios
28+
----------------
29+
Without mitigation, GDS can infer stale data across virtually all
30+
permission boundaries:
31+
32+
Non-enclaves can infer SGX enclave data
33+
Userspace can infer kernel data
34+
Guests can infer data from hosts
35+
Guest can infer guest from other guests
36+
Users can infer data from other users
37+
38+
Because of this, it is important to ensure that the mitigation stays enabled in
39+
lower-privilege contexts like guests and when running outside SGX enclaves.
40+
41+
The hardware enforces the mitigation for SGX. Likewise, VMMs should ensure
42+
that guests are not allowed to disable the GDS mitigation. If a host erred and
43+
allowed this, a guest could theoretically disable GDS mitigation, mount an
44+
attack, and re-enable it.
45+
46+
Mitigation mechanism
47+
--------------------
48+
This issue is mitigated in microcode. The microcode defines the following new
49+
bits:
50+
51+
================================ === ============================
52+
IA32_ARCH_CAPABILITIES[GDS_CTRL] R/O Enumerates GDS vulnerability
53+
and mitigation support.
54+
IA32_ARCH_CAPABILITIES[GDS_NO] R/O Processor is not vulnerable.
55+
IA32_MCU_OPT_CTRL[GDS_MITG_DIS] R/W Disables the mitigation
56+
0 by default.
57+
IA32_MCU_OPT_CTRL[GDS_MITG_LOCK] R/W Locks GDS_MITG_DIS=0. Writes
58+
to GDS_MITG_DIS are ignored
59+
Can't be cleared once set.
60+
================================ === ============================
61+
62+
GDS can also be mitigated on systems that don't have updated microcode by
63+
disabling AVX. This can be done by setting "clearcpuid=avx" on the kernel
64+
command-line.
65+
66+
Mitigation control on the kernel command line
67+
---------------------------------------------
68+
The mitigation can be disabled by setting "gather_data_sampling=off" or
69+
"mitigations=off" on the kernel command line. Not specifying either will
70+
default to the mitigation being enabled.
71+
72+
GDS System Information
73+
------------------------
74+
The kernel provides vulnerability status information through sysfs. For
75+
GDS this can be accessed by the following sysfs file:
76+
77+
/sys/devices/system/cpu/vulnerabilities/gather_data_sampling
78+
79+
The possible values contained in this file are:
80+
81+
============================== =============================================
82+
Not affected Processor not vulnerable.
83+
Vulnerable Processor vulnerable and mitigation disabled.
84+
Vulnerable: No microcode Processor vulnerable and microcode is missing
85+
mitigation.
86+
Mitigation: Microcode Processor is vulnerable and mitigation is in
87+
effect.
88+
Mitigation: Microcode (locked) Processor is vulnerable and mitigation is in
89+
effect and cannot be disabled.
90+
Unknown: Dependent on
91+
hypervisor status Running on a virtual guest processor that is
92+
affected but with no way to know if host
93+
processor is mitigated or vulnerable.
94+
============================== =============================================
95+
96+
GDS Default mitigation
97+
----------------------
98+
The updated microcode will enable the mitigation by default. The kernel's
99+
default action is to leave the mitigation enabled.

Documentation/admin-guide/hw-vuln/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ are configurable at compile, boot or run time.
1919
l1d_flush.rst
2020
processor_mmio_stale_data.rst
2121
cross-thread-rsb.rst
22+
gather_data_sampling.rst

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,6 +1593,20 @@
15931593
Format: off | on
15941594
default: on
15951595

1596+
gather_data_sampling=
1597+
[X86,INTEL] Control the Gather Data Sampling (GDS)
1598+
mitigation.
1599+
1600+
Gather Data Sampling is a hardware vulnerability which
1601+
allows unprivileged speculative access to data which was
1602+
previously stored in vector registers.
1603+
1604+
This issue is mitigated by default in updated microcode.
1605+
The mitigation may have a performance impact but can be
1606+
disabled.
1607+
1608+
off: Disable GDS mitigation.
1609+
15961610
gcov_persist= [GCOV] When non-zero (default), profiling data for
15971611
kernel modules is saved and remains accessible via
15981612
debugfs, even when the module is unloaded/reloaded.
@@ -3228,24 +3242,25 @@
32283242
Disable all optional CPU mitigations. This
32293243
improves system performance, but it may also
32303244
expose users to several CPU vulnerabilities.
3231-
Equivalent to: nopti [X86,PPC]
3232-
if nokaslr then kpti=0 [ARM64]
3233-
nospectre_v1 [X86,PPC]
3234-
nobp=0 [S390]
3235-
nospectre_v2 [X86,PPC,S390,ARM64]
3236-
spectre_v2_user=off [X86]
3237-
spec_store_bypass_disable=off [X86,PPC]
3238-
ssbd=force-off [ARM64]
3239-
nospectre_bhb [ARM64]
3245+
Equivalent to: if nokaslr then kpti=0 [ARM64]
3246+
gather_data_sampling=off [X86]
3247+
kvm.nx_huge_pages=off [X86]
32403248
l1tf=off [X86]
32413249
mds=off [X86]
3242-
tsx_async_abort=off [X86]
3243-
kvm.nx_huge_pages=off [X86]
3244-
srbds=off [X86,INTEL]
3250+
mmio_stale_data=off [X86]
32453251
no_entry_flush [PPC]
32463252
no_uaccess_flush [PPC]
3247-
mmio_stale_data=off [X86]
3253+
nobp=0 [S390]
3254+
nopti [X86,PPC]
3255+
nospectre_bhb [ARM64]
3256+
nospectre_v1 [X86,PPC]
3257+
nospectre_v2 [X86,PPC,S390,ARM64]
32483258
retbleed=off [X86]
3259+
spec_store_bypass_disable=off [X86,PPC]
3260+
spectre_v2_user=off [X86]
3261+
srbds=off [X86,INTEL]
3262+
ssbd=force-off [ARM64]
3263+
tsx_async_abort=off [X86]
32493264

32503265
Exceptions:
32513266
This does not have any effect on

arch/x86/include/asm/cpufeatures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,5 +464,6 @@
464464
#define X86_BUG_RETBLEED X86_BUG(27) /* CPU is affected by RETBleed */
465465
#define X86_BUG_EIBRS_PBRSB X86_BUG(28) /* EIBRS is vulnerable to Post Barrier RSB Predictions */
466466
#define X86_BUG_SMT_RSB X86_BUG(29) /* CPU is vulnerable to Cross-Thread Return Address Predictions */
467+
#define X86_BUG_GDS X86_BUG(30) /* CPU is affected by Gather Data Sampling */
467468

468469
#endif /* _ASM_X86_CPUFEATURES_H */

arch/x86/include/asm/msr-index.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,15 @@
158158
* Not susceptible to Post-Barrier
159159
* Return Stack Buffer Predictions.
160160
*/
161+
#define ARCH_CAP_GDS_CTRL BIT(25) /*
162+
* CPU is vulnerable to Gather
163+
* Data Sampling (GDS) and
164+
* has controls for mitigation.
165+
*/
166+
#define ARCH_CAP_GDS_NO BIT(26) /*
167+
* CPU is not vulnerable to Gather
168+
* Data Sampling (GDS).
169+
*/
161170

162171
#define ARCH_CAP_XAPIC_DISABLE BIT(21) /*
163172
* IA32_XAPIC_DISABLE_STATUS MSR
@@ -181,6 +190,8 @@
181190
#define RNGDS_MITG_DIS BIT(0) /* SRBDS support */
182191
#define RTM_ALLOW BIT(1) /* TSX development mode */
183192
#define FB_CLEAR_DIS BIT(3) /* CPU Fill buffer clear disable */
193+
#define GDS_MITG_DIS BIT(4) /* Disable GDS mitigation */
194+
#define GDS_MITG_LOCKED BIT(5) /* GDS mitigation locked */
184195

185196
#define MSR_IA32_SYSENTER_CS 0x00000174
186197
#define MSR_IA32_SYSENTER_ESP 0x00000175

arch/x86/kernel/cpu/bugs.c

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ static void __init taa_select_mitigation(void);
4646
static void __init mmio_select_mitigation(void);
4747
static void __init srbds_select_mitigation(void);
4848
static void __init l1d_flush_select_mitigation(void);
49+
static void __init gds_select_mitigation(void);
4950

5051
/* The base value of the SPEC_CTRL MSR without task-specific bits set */
5152
u64 x86_spec_ctrl_base;
@@ -159,6 +160,7 @@ void __init cpu_select_mitigations(void)
159160
md_clear_select_mitigation();
160161
srbds_select_mitigation();
161162
l1d_flush_select_mitigation();
163+
gds_select_mitigation();
162164
}
163165

164166
/*
@@ -644,6 +646,120 @@ static int __init l1d_flush_parse_cmdline(char *str)
644646
}
645647
early_param("l1d_flush", l1d_flush_parse_cmdline);
646648

649+
#undef pr_fmt
650+
#define pr_fmt(fmt) "GDS: " fmt
651+
652+
enum gds_mitigations {
653+
GDS_MITIGATION_OFF,
654+
GDS_MITIGATION_UCODE_NEEDED,
655+
GDS_MITIGATION_FULL,
656+
GDS_MITIGATION_FULL_LOCKED,
657+
GDS_MITIGATION_HYPERVISOR,
658+
};
659+
660+
static enum gds_mitigations gds_mitigation __ro_after_init = GDS_MITIGATION_FULL;
661+
662+
static const char * const gds_strings[] = {
663+
[GDS_MITIGATION_OFF] = "Vulnerable",
664+
[GDS_MITIGATION_UCODE_NEEDED] = "Vulnerable: No microcode",
665+
[GDS_MITIGATION_FULL] = "Mitigation: Microcode",
666+
[GDS_MITIGATION_FULL_LOCKED] = "Mitigation: Microcode (locked)",
667+
[GDS_MITIGATION_HYPERVISOR] = "Unknown: Dependent on hypervisor status",
668+
};
669+
670+
void update_gds_msr(void)
671+
{
672+
u64 mcu_ctrl_after;
673+
u64 mcu_ctrl;
674+
675+
switch (gds_mitigation) {
676+
case GDS_MITIGATION_OFF:
677+
rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl);
678+
mcu_ctrl |= GDS_MITG_DIS;
679+
break;
680+
case GDS_MITIGATION_FULL_LOCKED:
681+
/*
682+
* The LOCKED state comes from the boot CPU. APs might not have
683+
* the same state. Make sure the mitigation is enabled on all
684+
* CPUs.
685+
*/
686+
case GDS_MITIGATION_FULL:
687+
rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl);
688+
mcu_ctrl &= ~GDS_MITG_DIS;
689+
break;
690+
case GDS_MITIGATION_UCODE_NEEDED:
691+
case GDS_MITIGATION_HYPERVISOR:
692+
return;
693+
};
694+
695+
wrmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl);
696+
697+
/*
698+
* Check to make sure that the WRMSR value was not ignored. Writes to
699+
* GDS_MITG_DIS will be ignored if this processor is locked but the boot
700+
* processor was not.
701+
*/
702+
rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl_after);
703+
WARN_ON_ONCE(mcu_ctrl != mcu_ctrl_after);
704+
}
705+
706+
static void __init gds_select_mitigation(void)
707+
{
708+
u64 mcu_ctrl;
709+
710+
if (!boot_cpu_has_bug(X86_BUG_GDS))
711+
return;
712+
713+
if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) {
714+
gds_mitigation = GDS_MITIGATION_HYPERVISOR;
715+
goto out;
716+
}
717+
718+
if (cpu_mitigations_off())
719+
gds_mitigation = GDS_MITIGATION_OFF;
720+
/* Will verify below that mitigation _can_ be disabled */
721+
722+
/* No microcode */
723+
if (!(x86_read_arch_cap_msr() & ARCH_CAP_GDS_CTRL)) {
724+
gds_mitigation = GDS_MITIGATION_UCODE_NEEDED;
725+
goto out;
726+
}
727+
728+
rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl);
729+
if (mcu_ctrl & GDS_MITG_LOCKED) {
730+
if (gds_mitigation == GDS_MITIGATION_OFF)
731+
pr_warn("Mitigation locked. Disable failed.\n");
732+
733+
/*
734+
* The mitigation is selected from the boot CPU. All other CPUs
735+
* _should_ have the same state. If the boot CPU isn't locked
736+
* but others are then update_gds_msr() will WARN() of the state
737+
* mismatch. If the boot CPU is locked update_gds_msr() will
738+
* ensure the other CPUs have the mitigation enabled.
739+
*/
740+
gds_mitigation = GDS_MITIGATION_FULL_LOCKED;
741+
}
742+
743+
update_gds_msr();
744+
out:
745+
pr_info("%s\n", gds_strings[gds_mitigation]);
746+
}
747+
748+
static int __init gds_parse_cmdline(char *str)
749+
{
750+
if (!str)
751+
return -EINVAL;
752+
753+
if (!boot_cpu_has_bug(X86_BUG_GDS))
754+
return 0;
755+
756+
if (!strcmp(str, "off"))
757+
gds_mitigation = GDS_MITIGATION_OFF;
758+
759+
return 0;
760+
}
761+
early_param("gather_data_sampling", gds_parse_cmdline);
762+
647763
#undef pr_fmt
648764
#define pr_fmt(fmt) "Spectre V1 : " fmt
649765

@@ -2356,6 +2472,11 @@ static ssize_t retbleed_show_state(char *buf)
23562472
return sprintf(buf, "%s\n", retbleed_strings[retbleed_mitigation]);
23572473
}
23582474

2475+
static ssize_t gds_show_state(char *buf)
2476+
{
2477+
return sysfs_emit(buf, "%s\n", gds_strings[gds_mitigation]);
2478+
}
2479+
23592480
static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr,
23602481
char *buf, unsigned int bug)
23612482
{
@@ -2405,6 +2526,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
24052526
case X86_BUG_RETBLEED:
24062527
return retbleed_show_state(buf);
24072528

2529+
case X86_BUG_GDS:
2530+
return gds_show_state(buf);
2531+
24082532
default:
24092533
break;
24102534
}
@@ -2469,4 +2593,9 @@ ssize_t cpu_show_retbleed(struct device *dev, struct device_attribute *attr, cha
24692593
{
24702594
return cpu_show_common(dev, attr, buf, X86_BUG_RETBLEED);
24712595
}
2596+
2597+
ssize_t cpu_show_gds(struct device *dev, struct device_attribute *attr, char *buf)
2598+
{
2599+
return cpu_show_common(dev, attr, buf, X86_BUG_GDS);
2600+
}
24722601
#endif

0 commit comments

Comments
 (0)