Skip to content

Commit 0e33cf9

Browse files
committed
Merge tag 'rfds-for-linus-2024-03-11' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 RFDS mitigation from Dave Hansen: "RFDS is a CPU vulnerability that may allow a malicious userspace to infer stale register values from kernel space. Kernel registers can have all kinds of secrets in them so the mitigation is basically to wait until the kernel is about to return to userspace and has user values in the registers. At that point there is little chance of kernel secrets ending up in the registers and the microarchitectural state can be cleared. This leverages some recent robustness fixes for the existing MDS vulnerability. Both MDS and RFDS use the VERW instruction for mitigation" * tag 'rfds-for-linus-2024-03-11' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: KVM/x86: Export RFDS_NO and RFDS_CLEAR to guests x86/rfds: Mitigate Register File Data Sampling (RFDS) Documentation/hw-vuln: Add documentation for RFDS x86/mmio: Disable KVM mitigation when X86_FEATURE_CLEAR_CPU_BUF is set
2 parents 855684c + 2a01801 commit 0e33cf9

File tree

12 files changed

+278
-9
lines changed

12 files changed

+278
-9
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,7 @@ What: /sys/devices/system/cpu/vulnerabilities
516516
/sys/devices/system/cpu/vulnerabilities/mds
517517
/sys/devices/system/cpu/vulnerabilities/meltdown
518518
/sys/devices/system/cpu/vulnerabilities/mmio_stale_data
519+
/sys/devices/system/cpu/vulnerabilities/reg_file_data_sampling
519520
/sys/devices/system/cpu/vulnerabilities/retbleed
520521
/sys/devices/system/cpu/vulnerabilities/spec_store_bypass
521522
/sys/devices/system/cpu/vulnerabilities/spectre_v1

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ are configurable at compile, boot or run time.
2121
cross-thread-rsb
2222
srso
2323
gather_data_sampling
24+
reg-file-data-sampling
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
==================================
2+
Register File Data Sampling (RFDS)
3+
==================================
4+
5+
Register File Data Sampling (RFDS) is a microarchitectural vulnerability that
6+
only affects Intel Atom parts(also branded as E-cores). RFDS may allow
7+
a malicious actor to infer data values previously used in floating point
8+
registers, vector registers, or integer registers. RFDS does not provide the
9+
ability to choose which data is inferred. CVE-2023-28746 is assigned to RFDS.
10+
11+
Affected Processors
12+
===================
13+
Below is the list of affected Intel processors [#f1]_:
14+
15+
=================== ============
16+
Common name Family_Model
17+
=================== ============
18+
ATOM_GOLDMONT 06_5CH
19+
ATOM_GOLDMONT_D 06_5FH
20+
ATOM_GOLDMONT_PLUS 06_7AH
21+
ATOM_TREMONT_D 06_86H
22+
ATOM_TREMONT 06_96H
23+
ALDERLAKE 06_97H
24+
ALDERLAKE_L 06_9AH
25+
ATOM_TREMONT_L 06_9CH
26+
RAPTORLAKE 06_B7H
27+
RAPTORLAKE_P 06_BAH
28+
ATOM_GRACEMONT 06_BEH
29+
RAPTORLAKE_S 06_BFH
30+
=================== ============
31+
32+
As an exception to this table, Intel Xeon E family parts ALDERLAKE(06_97H) and
33+
RAPTORLAKE(06_B7H) codenamed Catlow are not affected. They are reported as
34+
vulnerable in Linux because they share the same family/model with an affected
35+
part. Unlike their affected counterparts, they do not enumerate RFDS_CLEAR or
36+
CPUID.HYBRID. This information could be used to distinguish between the
37+
affected and unaffected parts, but it is deemed not worth adding complexity as
38+
the reporting is fixed automatically when these parts enumerate RFDS_NO.
39+
40+
Mitigation
41+
==========
42+
Intel released a microcode update that enables software to clear sensitive
43+
information using the VERW instruction. Like MDS, RFDS deploys the same
44+
mitigation strategy to force the CPU to clear the affected buffers before an
45+
attacker can extract the secrets. This is achieved by using the otherwise
46+
unused and obsolete VERW instruction in combination with a microcode update.
47+
The microcode clears the affected CPU buffers when the VERW instruction is
48+
executed.
49+
50+
Mitigation points
51+
-----------------
52+
VERW is executed by the kernel before returning to user space, and by KVM
53+
before VMentry. None of the affected cores support SMT, so VERW is not required
54+
at C-state transitions.
55+
56+
New bits in IA32_ARCH_CAPABILITIES
57+
----------------------------------
58+
Newer processors and microcode update on existing affected processors added new
59+
bits to IA32_ARCH_CAPABILITIES MSR. These bits can be used to enumerate
60+
vulnerability and mitigation capability:
61+
62+
- Bit 27 - RFDS_NO - When set, processor is not affected by RFDS.
63+
- Bit 28 - RFDS_CLEAR - When set, processor is affected by RFDS, and has the
64+
microcode that clears the affected buffers on VERW execution.
65+
66+
Mitigation control on the kernel command line
67+
---------------------------------------------
68+
The kernel command line allows to control RFDS mitigation at boot time with the
69+
parameter "reg_file_data_sampling=". The valid arguments are:
70+
71+
========== =================================================================
72+
on If the CPU is vulnerable, enable mitigation; CPU buffer clearing
73+
on exit to userspace and before entering a VM.
74+
off Disables mitigation.
75+
========== =================================================================
76+
77+
Mitigation default is selected by CONFIG_MITIGATION_RFDS.
78+
79+
Mitigation status information
80+
-----------------------------
81+
The Linux kernel provides a sysfs interface to enumerate the current
82+
vulnerability status of the system: whether the system is vulnerable, and
83+
which mitigations are active. The relevant sysfs file is:
84+
85+
/sys/devices/system/cpu/vulnerabilities/reg_file_data_sampling
86+
87+
The possible values in this file are:
88+
89+
.. list-table::
90+
91+
* - 'Not affected'
92+
- The processor is not vulnerable
93+
* - 'Vulnerable'
94+
- The processor is vulnerable, but no mitigation enabled
95+
* - 'Vulnerable: No microcode'
96+
- The processor is vulnerable but microcode is not updated.
97+
* - 'Mitigation: Clear Register File'
98+
- The processor is vulnerable and the CPU buffer clearing mitigation is
99+
enabled.
100+
101+
References
102+
----------
103+
.. [#f1] Affected Processors
104+
https://www.intel.com/content/www/us/en/developer/topic-technology/software-security-guidance/processors-affected-consolidated-product-cpu-model.html

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,26 @@
11361136
The filter can be disabled or changed to another
11371137
driver later using sysfs.
11381138

1139+
reg_file_data_sampling=
1140+
[X86] Controls mitigation for Register File Data
1141+
Sampling (RFDS) vulnerability. RFDS is a CPU
1142+
vulnerability which may allow userspace to infer
1143+
kernel data values previously stored in floating point
1144+
registers, vector registers, or integer registers.
1145+
RFDS only affects Intel Atom processors.
1146+
1147+
on: Turns ON the mitigation.
1148+
off: Turns OFF the mitigation.
1149+
1150+
This parameter overrides the compile time default set
1151+
by CONFIG_MITIGATION_RFDS. Mitigation cannot be
1152+
disabled when other VERW based mitigations (like MDS)
1153+
are enabled. In order to disable RFDS mitigation all
1154+
VERW based mitigations need to be disabled.
1155+
1156+
For details see:
1157+
Documentation/admin-guide/hw-vuln/reg-file-data-sampling.rst
1158+
11391159
driver_async_probe= [KNL]
11401160
List of driver names to be probed asynchronously. *
11411161
matches with all driver names. If * is specified, the
@@ -3394,6 +3414,7 @@
33943414
nospectre_bhb [ARM64]
33953415
nospectre_v1 [X86,PPC]
33963416
nospectre_v2 [X86,PPC,S390,ARM64]
3417+
reg_file_data_sampling=off [X86]
33973418
retbleed=off [X86]
33983419
spec_rstack_overflow=off [X86]
33993420
spec_store_bypass_disable=off [X86,PPC]

arch/x86/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2623,6 +2623,17 @@ config MITIGATION_GDS_FORCE
26232623

26242624
If in doubt, say N.
26252625

2626+
config MITIGATION_RFDS
2627+
bool "RFDS Mitigation"
2628+
depends on CPU_SUP_INTEL
2629+
default y
2630+
help
2631+
Enable mitigation for Register File Data Sampling (RFDS) by default.
2632+
RFDS is a hardware vulnerability which affects Intel Atom CPUs. It
2633+
allows unprivileged speculative access to stale data previously
2634+
stored in floating point, vector and integer registers.
2635+
See also <file:Documentation/admin-guide/hw-vuln/reg-file-data-sampling.rst>
2636+
26262637
endif
26272638

26282639
config ARCH_HAS_ADD_PAGES

arch/x86/include/asm/cpufeatures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,4 +506,5 @@
506506
/* BUG word 2 */
507507
#define X86_BUG_SRSO X86_BUG(1*32 + 0) /* AMD SRSO bug */
508508
#define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* AMD DIV0 speculation bug */
509+
#define X86_BUG_RFDS X86_BUG(1*32 + 2) /* CPU is vulnerable to Register File Data Sampling */
509510
#endif /* _ASM_X86_CPUFEATURES_H */

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,14 @@
176176
* CPU is not vulnerable to Gather
177177
* Data Sampling (GDS).
178178
*/
179+
#define ARCH_CAP_RFDS_NO BIT(27) /*
180+
* Not susceptible to Register
181+
* File Data Sampling.
182+
*/
183+
#define ARCH_CAP_RFDS_CLEAR BIT(28) /*
184+
* VERW clears CPU Register
185+
* File.
186+
*/
179187

180188
#define ARCH_CAP_XAPIC_DISABLE BIT(21) /*
181189
* IA32_XAPIC_DISABLE_STATUS MSR

arch/x86/kernel/cpu/bugs.c

Lines changed: 87 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,13 @@ static void __init mmio_select_mitigation(void)
422422
if (boot_cpu_has_bug(X86_BUG_MDS) || (boot_cpu_has_bug(X86_BUG_TAA) &&
423423
boot_cpu_has(X86_FEATURE_RTM)))
424424
setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
425+
426+
/*
427+
* X86_FEATURE_CLEAR_CPU_BUF could be enabled by other VERW based
428+
* mitigations, disable KVM-only mitigation in that case.
429+
*/
430+
if (boot_cpu_has(X86_FEATURE_CLEAR_CPU_BUF))
431+
static_branch_disable(&mmio_stale_data_clear);
425432
else
426433
static_branch_enable(&mmio_stale_data_clear);
427434

@@ -473,6 +480,57 @@ static int __init mmio_stale_data_parse_cmdline(char *str)
473480
}
474481
early_param("mmio_stale_data", mmio_stale_data_parse_cmdline);
475482

483+
#undef pr_fmt
484+
#define pr_fmt(fmt) "Register File Data Sampling: " fmt
485+
486+
enum rfds_mitigations {
487+
RFDS_MITIGATION_OFF,
488+
RFDS_MITIGATION_VERW,
489+
RFDS_MITIGATION_UCODE_NEEDED,
490+
};
491+
492+
/* Default mitigation for Register File Data Sampling */
493+
static enum rfds_mitigations rfds_mitigation __ro_after_init =
494+
IS_ENABLED(CONFIG_MITIGATION_RFDS) ? RFDS_MITIGATION_VERW : RFDS_MITIGATION_OFF;
495+
496+
static const char * const rfds_strings[] = {
497+
[RFDS_MITIGATION_OFF] = "Vulnerable",
498+
[RFDS_MITIGATION_VERW] = "Mitigation: Clear Register File",
499+
[RFDS_MITIGATION_UCODE_NEEDED] = "Vulnerable: No microcode",
500+
};
501+
502+
static void __init rfds_select_mitigation(void)
503+
{
504+
if (!boot_cpu_has_bug(X86_BUG_RFDS) || cpu_mitigations_off()) {
505+
rfds_mitigation = RFDS_MITIGATION_OFF;
506+
return;
507+
}
508+
if (rfds_mitigation == RFDS_MITIGATION_OFF)
509+
return;
510+
511+
if (x86_read_arch_cap_msr() & ARCH_CAP_RFDS_CLEAR)
512+
setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
513+
else
514+
rfds_mitigation = RFDS_MITIGATION_UCODE_NEEDED;
515+
}
516+
517+
static __init int rfds_parse_cmdline(char *str)
518+
{
519+
if (!str)
520+
return -EINVAL;
521+
522+
if (!boot_cpu_has_bug(X86_BUG_RFDS))
523+
return 0;
524+
525+
if (!strcmp(str, "off"))
526+
rfds_mitigation = RFDS_MITIGATION_OFF;
527+
else if (!strcmp(str, "on"))
528+
rfds_mitigation = RFDS_MITIGATION_VERW;
529+
530+
return 0;
531+
}
532+
early_param("reg_file_data_sampling", rfds_parse_cmdline);
533+
476534
#undef pr_fmt
477535
#define pr_fmt(fmt) "" fmt
478536

@@ -498,11 +556,19 @@ static void __init md_clear_update_mitigation(void)
498556
taa_mitigation = TAA_MITIGATION_VERW;
499557
taa_select_mitigation();
500558
}
501-
if (mmio_mitigation == MMIO_MITIGATION_OFF &&
502-
boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) {
559+
/*
560+
* MMIO_MITIGATION_OFF is not checked here so that mmio_stale_data_clear
561+
* gets updated correctly as per X86_FEATURE_CLEAR_CPU_BUF state.
562+
*/
563+
if (boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) {
503564
mmio_mitigation = MMIO_MITIGATION_VERW;
504565
mmio_select_mitigation();
505566
}
567+
if (rfds_mitigation == RFDS_MITIGATION_OFF &&
568+
boot_cpu_has_bug(X86_BUG_RFDS)) {
569+
rfds_mitigation = RFDS_MITIGATION_VERW;
570+
rfds_select_mitigation();
571+
}
506572
out:
507573
if (boot_cpu_has_bug(X86_BUG_MDS))
508574
pr_info("MDS: %s\n", mds_strings[mds_mitigation]);
@@ -512,18 +578,21 @@ static void __init md_clear_update_mitigation(void)
512578
pr_info("MMIO Stale Data: %s\n", mmio_strings[mmio_mitigation]);
513579
else if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN))
514580
pr_info("MMIO Stale Data: Unknown: No mitigations\n");
581+
if (boot_cpu_has_bug(X86_BUG_RFDS))
582+
pr_info("Register File Data Sampling: %s\n", rfds_strings[rfds_mitigation]);
515583
}
516584

517585
static void __init md_clear_select_mitigation(void)
518586
{
519587
mds_select_mitigation();
520588
taa_select_mitigation();
521589
mmio_select_mitigation();
590+
rfds_select_mitigation();
522591

523592
/*
524-
* As MDS, TAA and MMIO Stale Data mitigations are inter-related, update
525-
* and print their mitigation after MDS, TAA and MMIO Stale Data
526-
* mitigation selection is done.
593+
* As these mitigations are inter-related and rely on VERW instruction
594+
* to clear the microarchitural buffers, update and print their status
595+
* after mitigation selection is done for each of these vulnerabilities.
527596
*/
528597
md_clear_update_mitigation();
529598
}
@@ -2613,6 +2682,11 @@ static ssize_t mmio_stale_data_show_state(char *buf)
26132682
sched_smt_active() ? "vulnerable" : "disabled");
26142683
}
26152684

2685+
static ssize_t rfds_show_state(char *buf)
2686+
{
2687+
return sysfs_emit(buf, "%s\n", rfds_strings[rfds_mitigation]);
2688+
}
2689+
26162690
static char *stibp_state(void)
26172691
{
26182692
if (spectre_v2_in_eibrs_mode(spectre_v2_enabled) &&
@@ -2772,6 +2846,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
27722846
case X86_BUG_GDS:
27732847
return gds_show_state(buf);
27742848

2849+
case X86_BUG_RFDS:
2850+
return rfds_show_state(buf);
2851+
27752852
default:
27762853
break;
27772854
}
@@ -2846,6 +2923,11 @@ ssize_t cpu_show_gds(struct device *dev, struct device_attribute *attr, char *bu
28462923
{
28472924
return cpu_show_common(dev, attr, buf, X86_BUG_GDS);
28482925
}
2926+
2927+
ssize_t cpu_show_reg_file_data_sampling(struct device *dev, struct device_attribute *attr, char *buf)
2928+
{
2929+
return cpu_show_common(dev, attr, buf, X86_BUG_RFDS);
2930+
}
28492931
#endif
28502932

28512933
void __warn_thunk(void)

0 commit comments

Comments
 (0)