]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-5.10/x86-rfds-mitigate-register-file-data-sampling-rfds.patch
5.10-stable patches
[thirdparty/kernel/stable-queue.git] / queue-5.10 / x86-rfds-mitigate-register-file-data-sampling-rfds.patch
1 From stable+bounces-27551-greg=kroah.com@vger.kernel.org Tue Mar 12 23:41:24 2024
2 From: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
3 Date: Tue, 12 Mar 2024 15:41:19 -0700
4 Subject: x86/rfds: Mitigate Register File Data Sampling (RFDS)
5 To: stable@vger.kernel.org
6 Cc: Dave Hansen <dave.hansen@linux.intel.com>, Thomas Gleixner <tglx@linutronix.de>, Josh Poimboeuf <jpoimboe@kernel.org>
7 Message-ID: <20240312-delay-verw-backport-5-10-y-v2-10-ad081ccd89ca@linux.intel.com>
8 Content-Disposition: inline
9
10 From: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
11
12 commit 8076fcde016c9c0e0660543e67bff86cb48a7c9c upstream.
13
14 RFDS is a CPU vulnerability that may allow userspace to infer kernel
15 stale data previously used in floating point registers, vector registers
16 and integer registers. RFDS only affects certain Intel Atom processors.
17
18 Intel released a microcode update that uses VERW instruction to clear
19 the affected CPU buffers. Unlike MDS, none of the affected cores support
20 SMT.
21
22 Add RFDS bug infrastructure and enable the VERW based mitigation by
23 default, that clears the affected buffers just before exiting to
24 userspace. Also add sysfs reporting and cmdline parameter
25 "reg_file_data_sampling" to control the mitigation.
26
27 For details see:
28 Documentation/admin-guide/hw-vuln/reg-file-data-sampling.rst
29
30 [ pawan: - Resolved conflicts in sysfs reporting.
31 - s/ATOM_GRACEMONT/ALDERLAKE_N/ATOM_GRACEMONT is called
32 ALDERLAKE_N in 6.6. ]
33
34 Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
35 Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
36 Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
37 Acked-by: Josh Poimboeuf <jpoimboe@kernel.org>
38 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
39 ---
40 Documentation/ABI/testing/sysfs-devices-system-cpu | 1
41 Documentation/admin-guide/kernel-parameters.txt | 21 +++++
42 arch/x86/Kconfig | 11 ++
43 arch/x86/include/asm/cpufeatures.h | 1
44 arch/x86/include/asm/msr-index.h | 8 ++
45 arch/x86/kernel/cpu/bugs.c | 78 ++++++++++++++++++++-
46 arch/x86/kernel/cpu/common.c | 38 +++++++++-
47 drivers/base/cpu.c | 8 ++
48 include/linux/cpu.h | 2
49 9 files changed, 162 insertions(+), 6 deletions(-)
50
51 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu
52 +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
53 @@ -507,6 +507,7 @@ What: /sys/devices/system/cpu/vulnerabi
54 /sys/devices/system/cpu/vulnerabilities/mds
55 /sys/devices/system/cpu/vulnerabilities/meltdown
56 /sys/devices/system/cpu/vulnerabilities/mmio_stale_data
57 + /sys/devices/system/cpu/vulnerabilities/reg_file_data_sampling
58 /sys/devices/system/cpu/vulnerabilities/retbleed
59 /sys/devices/system/cpu/vulnerabilities/spec_store_bypass
60 /sys/devices/system/cpu/vulnerabilities/spectre_v1
61 --- a/Documentation/admin-guide/kernel-parameters.txt
62 +++ b/Documentation/admin-guide/kernel-parameters.txt
63 @@ -993,6 +993,26 @@
64 The filter can be disabled or changed to another
65 driver later using sysfs.
66
67 + reg_file_data_sampling=
68 + [X86] Controls mitigation for Register File Data
69 + Sampling (RFDS) vulnerability. RFDS is a CPU
70 + vulnerability which may allow userspace to infer
71 + kernel data values previously stored in floating point
72 + registers, vector registers, or integer registers.
73 + RFDS only affects Intel Atom processors.
74 +
75 + on: Turns ON the mitigation.
76 + off: Turns OFF the mitigation.
77 +
78 + This parameter overrides the compile time default set
79 + by CONFIG_MITIGATION_RFDS. Mitigation cannot be
80 + disabled when other VERW based mitigations (like MDS)
81 + are enabled. In order to disable RFDS mitigation all
82 + VERW based mitigations need to be disabled.
83 +
84 + For details see:
85 + Documentation/admin-guide/hw-vuln/reg-file-data-sampling.rst
86 +
87 driver_async_probe= [KNL]
88 List of driver names to be probed asynchronously.
89 Format: <driver_name1>,<driver_name2>...
90 @@ -2919,6 +2939,7 @@
91 nopti [X86,PPC]
92 nospectre_v1 [X86,PPC]
93 nospectre_v2 [X86,PPC,S390,ARM64]
94 + reg_file_data_sampling=off [X86]
95 retbleed=off [X86]
96 spec_store_bypass_disable=off [X86,PPC]
97 spectre_v2_user=off [X86]
98 --- a/arch/x86/Kconfig
99 +++ b/arch/x86/Kconfig
100 @@ -2508,6 +2508,17 @@ config GDS_FORCE_MITIGATION
101
102 If in doubt, say N.
103
104 +config MITIGATION_RFDS
105 + bool "RFDS Mitigation"
106 + depends on CPU_SUP_INTEL
107 + default y
108 + help
109 + Enable mitigation for Register File Data Sampling (RFDS) by default.
110 + RFDS is a hardware vulnerability which affects Intel Atom CPUs. It
111 + allows unprivileged speculative access to stale data previously
112 + stored in floating point, vector and integer registers.
113 + See also <file:Documentation/admin-guide/hw-vuln/reg-file-data-sampling.rst>
114 +
115 endif
116
117 config ARCH_HAS_ADD_PAGES
118 --- a/arch/x86/include/asm/cpufeatures.h
119 +++ b/arch/x86/include/asm/cpufeatures.h
120 @@ -454,4 +454,5 @@
121 /* BUG word 2 */
122 #define X86_BUG_SRSO X86_BUG(1*32 + 0) /* AMD SRSO bug */
123 #define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* AMD DIV0 speculation bug */
124 +#define X86_BUG_RFDS X86_BUG(1*32 + 2) /* CPU is vulnerable to Register File Data Sampling */
125 #endif /* _ASM_X86_CPUFEATURES_H */
126 --- a/arch/x86/include/asm/msr-index.h
127 +++ b/arch/x86/include/asm/msr-index.h
128 @@ -168,6 +168,14 @@
129 * CPU is not vulnerable to Gather
130 * Data Sampling (GDS).
131 */
132 +#define ARCH_CAP_RFDS_NO BIT(27) /*
133 + * Not susceptible to Register
134 + * File Data Sampling.
135 + */
136 +#define ARCH_CAP_RFDS_CLEAR BIT(28) /*
137 + * VERW clears CPU Register
138 + * File.
139 + */
140
141 #define MSR_IA32_FLUSH_CMD 0x0000010b
142 #define L1D_FLUSH BIT(0) /*
143 --- a/arch/x86/kernel/cpu/bugs.c
144 +++ b/arch/x86/kernel/cpu/bugs.c
145 @@ -478,6 +478,57 @@ static int __init mmio_stale_data_parse_
146 early_param("mmio_stale_data", mmio_stale_data_parse_cmdline);
147
148 #undef pr_fmt
149 +#define pr_fmt(fmt) "Register File Data Sampling: " fmt
150 +
151 +enum rfds_mitigations {
152 + RFDS_MITIGATION_OFF,
153 + RFDS_MITIGATION_VERW,
154 + RFDS_MITIGATION_UCODE_NEEDED,
155 +};
156 +
157 +/* Default mitigation for Register File Data Sampling */
158 +static enum rfds_mitigations rfds_mitigation __ro_after_init =
159 + IS_ENABLED(CONFIG_MITIGATION_RFDS) ? RFDS_MITIGATION_VERW : RFDS_MITIGATION_OFF;
160 +
161 +static const char * const rfds_strings[] = {
162 + [RFDS_MITIGATION_OFF] = "Vulnerable",
163 + [RFDS_MITIGATION_VERW] = "Mitigation: Clear Register File",
164 + [RFDS_MITIGATION_UCODE_NEEDED] = "Vulnerable: No microcode",
165 +};
166 +
167 +static void __init rfds_select_mitigation(void)
168 +{
169 + if (!boot_cpu_has_bug(X86_BUG_RFDS) || cpu_mitigations_off()) {
170 + rfds_mitigation = RFDS_MITIGATION_OFF;
171 + return;
172 + }
173 + if (rfds_mitigation == RFDS_MITIGATION_OFF)
174 + return;
175 +
176 + if (x86_read_arch_cap_msr() & ARCH_CAP_RFDS_CLEAR)
177 + setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
178 + else
179 + rfds_mitigation = RFDS_MITIGATION_UCODE_NEEDED;
180 +}
181 +
182 +static __init int rfds_parse_cmdline(char *str)
183 +{
184 + if (!str)
185 + return -EINVAL;
186 +
187 + if (!boot_cpu_has_bug(X86_BUG_RFDS))
188 + return 0;
189 +
190 + if (!strcmp(str, "off"))
191 + rfds_mitigation = RFDS_MITIGATION_OFF;
192 + else if (!strcmp(str, "on"))
193 + rfds_mitigation = RFDS_MITIGATION_VERW;
194 +
195 + return 0;
196 +}
197 +early_param("reg_file_data_sampling", rfds_parse_cmdline);
198 +
199 +#undef pr_fmt
200 #define pr_fmt(fmt) "" fmt
201
202 static void __init md_clear_update_mitigation(void)
203 @@ -510,6 +561,11 @@ static void __init md_clear_update_mitig
204 mmio_mitigation = MMIO_MITIGATION_VERW;
205 mmio_select_mitigation();
206 }
207 + if (rfds_mitigation == RFDS_MITIGATION_OFF &&
208 + boot_cpu_has_bug(X86_BUG_RFDS)) {
209 + rfds_mitigation = RFDS_MITIGATION_VERW;
210 + rfds_select_mitigation();
211 + }
212 out:
213 if (boot_cpu_has_bug(X86_BUG_MDS))
214 pr_info("MDS: %s\n", mds_strings[mds_mitigation]);
215 @@ -519,6 +575,8 @@ out:
216 pr_info("MMIO Stale Data: %s\n", mmio_strings[mmio_mitigation]);
217 else if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN))
218 pr_info("MMIO Stale Data: Unknown: No mitigations\n");
219 + if (boot_cpu_has_bug(X86_BUG_RFDS))
220 + pr_info("Register File Data Sampling: %s\n", rfds_strings[rfds_mitigation]);
221 }
222
223 static void __init md_clear_select_mitigation(void)
224 @@ -526,11 +584,12 @@ static void __init md_clear_select_mitig
225 mds_select_mitigation();
226 taa_select_mitigation();
227 mmio_select_mitigation();
228 + rfds_select_mitigation();
229
230 /*
231 - * As MDS, TAA and MMIO Stale Data mitigations are inter-related, update
232 - * and print their mitigation after MDS, TAA and MMIO Stale Data
233 - * mitigation selection is done.
234 + * As these mitigations are inter-related and rely on VERW instruction
235 + * to clear the microarchitural buffers, update and print their status
236 + * after mitigation selection is done for each of these vulnerabilities.
237 */
238 md_clear_update_mitigation();
239 }
240 @@ -2530,6 +2589,11 @@ static ssize_t mmio_stale_data_show_stat
241 sched_smt_active() ? "vulnerable" : "disabled");
242 }
243
244 +static ssize_t rfds_show_state(char *buf)
245 +{
246 + return sysfs_emit(buf, "%s\n", rfds_strings[rfds_mitigation]);
247 +}
248 +
249 static char *stibp_state(void)
250 {
251 if (spectre_v2_in_eibrs_mode(spectre_v2_enabled))
252 @@ -2690,6 +2754,9 @@ static ssize_t cpu_show_common(struct de
253 case X86_BUG_SRSO:
254 return srso_show_state(buf);
255
256 + case X86_BUG_RFDS:
257 + return rfds_show_state(buf);
258 +
259 default:
260 break;
261 }
262 @@ -2764,4 +2831,9 @@ ssize_t cpu_show_spec_rstack_overflow(st
263 {
264 return cpu_show_common(dev, attr, buf, X86_BUG_SRSO);
265 }
266 +
267 +ssize_t cpu_show_reg_file_data_sampling(struct device *dev, struct device_attribute *attr, char *buf)
268 +{
269 + return cpu_show_common(dev, attr, buf, X86_BUG_RFDS);
270 +}
271 #endif
272 --- a/arch/x86/kernel/cpu/common.c
273 +++ b/arch/x86/kernel/cpu/common.c
274 @@ -1132,6 +1132,8 @@ static const __initconst struct x86_cpu_
275 #define SRSO BIT(5)
276 /* CPU is affected by GDS */
277 #define GDS BIT(6)
278 +/* CPU is affected by Register File Data Sampling */
279 +#define RFDS BIT(7)
280
281 static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
282 VULNBL_INTEL_STEPPINGS(IVYBRIDGE, X86_STEPPING_ANY, SRBDS),
283 @@ -1159,9 +1161,18 @@ static const struct x86_cpu_id cpu_vuln_
284 VULNBL_INTEL_STEPPINGS(TIGERLAKE, X86_STEPPING_ANY, GDS),
285 VULNBL_INTEL_STEPPINGS(LAKEFIELD, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED),
286 VULNBL_INTEL_STEPPINGS(ROCKETLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS),
287 - VULNBL_INTEL_STEPPINGS(ATOM_TREMONT, X86_STEPPING_ANY, MMIO | MMIO_SBDS),
288 - VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_D, X86_STEPPING_ANY, MMIO),
289 - VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS),
290 + VULNBL_INTEL_STEPPINGS(ALDERLAKE, X86_STEPPING_ANY, RFDS),
291 + VULNBL_INTEL_STEPPINGS(ALDERLAKE_L, X86_STEPPING_ANY, RFDS),
292 + VULNBL_INTEL_STEPPINGS(RAPTORLAKE, X86_STEPPING_ANY, RFDS),
293 + VULNBL_INTEL_STEPPINGS(RAPTORLAKE_P, X86_STEPPING_ANY, RFDS),
294 + VULNBL_INTEL_STEPPINGS(RAPTORLAKE_S, X86_STEPPING_ANY, RFDS),
295 + VULNBL_INTEL_STEPPINGS(ALDERLAKE_N, X86_STEPPING_ANY, RFDS),
296 + VULNBL_INTEL_STEPPINGS(ATOM_TREMONT, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RFDS),
297 + VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_D, X86_STEPPING_ANY, MMIO | RFDS),
298 + VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RFDS),
299 + VULNBL_INTEL_STEPPINGS(ATOM_GOLDMONT, X86_STEPPING_ANY, RFDS),
300 + VULNBL_INTEL_STEPPINGS(ATOM_GOLDMONT_D, X86_STEPPING_ANY, RFDS),
301 + VULNBL_INTEL_STEPPINGS(ATOM_GOLDMONT_PLUS, X86_STEPPING_ANY, RFDS),
302
303 VULNBL_AMD(0x15, RETBLEED),
304 VULNBL_AMD(0x16, RETBLEED),
305 @@ -1195,6 +1206,24 @@ static bool arch_cap_mmio_immune(u64 ia3
306 ia32_cap & ARCH_CAP_SBDR_SSDP_NO);
307 }
308
309 +static bool __init vulnerable_to_rfds(u64 ia32_cap)
310 +{
311 + /* The "immunity" bit trumps everything else: */
312 + if (ia32_cap & ARCH_CAP_RFDS_NO)
313 + return false;
314 +
315 + /*
316 + * VMMs set ARCH_CAP_RFDS_CLEAR for processors not in the blacklist to
317 + * indicate that mitigation is needed because guest is running on a
318 + * vulnerable hardware or may migrate to such hardware:
319 + */
320 + if (ia32_cap & ARCH_CAP_RFDS_CLEAR)
321 + return true;
322 +
323 + /* Only consult the blacklist when there is no enumeration: */
324 + return cpu_matches(cpu_vuln_blacklist, RFDS);
325 +}
326 +
327 static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
328 {
329 u64 ia32_cap = x86_read_arch_cap_msr();
330 @@ -1303,6 +1332,9 @@ static void __init cpu_set_bug_bits(stru
331 setup_force_cpu_bug(X86_BUG_SRSO);
332 }
333
334 + if (vulnerable_to_rfds(ia32_cap))
335 + setup_force_cpu_bug(X86_BUG_RFDS);
336 +
337 if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
338 return;
339
340 --- a/drivers/base/cpu.c
341 +++ b/drivers/base/cpu.c
342 @@ -591,6 +591,12 @@ ssize_t __weak cpu_show_spec_rstack_over
343 return sysfs_emit(buf, "Not affected\n");
344 }
345
346 +ssize_t __weak cpu_show_reg_file_data_sampling(struct device *dev,
347 + struct device_attribute *attr, char *buf)
348 +{
349 + return sysfs_emit(buf, "Not affected\n");
350 +}
351 +
352 static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL);
353 static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL);
354 static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL);
355 @@ -604,6 +610,7 @@ static DEVICE_ATTR(mmio_stale_data, 0444
356 static DEVICE_ATTR(retbleed, 0444, cpu_show_retbleed, NULL);
357 static DEVICE_ATTR(gather_data_sampling, 0444, cpu_show_gds, NULL);
358 static DEVICE_ATTR(spec_rstack_overflow, 0444, cpu_show_spec_rstack_overflow, NULL);
359 +static DEVICE_ATTR(reg_file_data_sampling, 0444, cpu_show_reg_file_data_sampling, NULL);
360
361 static struct attribute *cpu_root_vulnerabilities_attrs[] = {
362 &dev_attr_meltdown.attr,
363 @@ -619,6 +626,7 @@ static struct attribute *cpu_root_vulner
364 &dev_attr_retbleed.attr,
365 &dev_attr_gather_data_sampling.attr,
366 &dev_attr_spec_rstack_overflow.attr,
367 + &dev_attr_reg_file_data_sampling.attr,
368 NULL
369 };
370
371 --- a/include/linux/cpu.h
372 +++ b/include/linux/cpu.h
373 @@ -74,6 +74,8 @@ extern ssize_t cpu_show_spec_rstack_over
374 struct device_attribute *attr, char *buf);
375 extern ssize_t cpu_show_gds(struct device *dev,
376 struct device_attribute *attr, char *buf);
377 +extern ssize_t cpu_show_reg_file_data_sampling(struct device *dev,
378 + struct device_attribute *attr, char *buf);
379
380 extern __printf(4, 5)
381 struct device *cpu_device_create(struct device *parent, void *drvdata,