/[packages]/updates/8/kernel/current/SOURCES/arm-report-spectre-v2-status-through-sysfs.patch
ViewVC logotype

Contents of /updates/8/kernel/current/SOURCES/arm-report-spectre-v2-status-through-sysfs.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1789982 - (show annotations) (download)
Tue Mar 8 23:11:59 2022 UTC (2 years, 1 month ago) by tmb
File size: 9076 byte(s)
add current -stable queue
1 From foo@baz Tue Mar 8 08:32:37 PM CET 2022
2 From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
3 Date: Fri, 11 Feb 2022 16:45:54 +0000
4 Subject: ARM: report Spectre v2 status through sysfs
5
6 From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
7
8 commit 9dd78194a3722fa6712192cdd4f7032d45112a9a upstream.
9
10 As per other architectures, add support for reporting the Spectre
11 vulnerability status via sysfs CPU.
12
13 Acked-by: Catalin Marinas <catalin.marinas@arm.com>
14 Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
15 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
16 ---
17 arch/arm/include/asm/spectre.h | 28 ++++++++
18 arch/arm/kernel/Makefile | 2
19 arch/arm/kernel/spectre.c | 54 +++++++++++++++
20 arch/arm/mm/Kconfig | 1
21 arch/arm/mm/proc-v7-bugs.c | 141 +++++++++++++++++++++++++++++------------
22 5 files changed, 187 insertions(+), 39 deletions(-)
23 create mode 100644 arch/arm/include/asm/spectre.h
24 create mode 100644 arch/arm/kernel/spectre.c
25
26 --- /dev/null
27 +++ b/arch/arm/include/asm/spectre.h
28 @@ -0,0 +1,28 @@
29 +/* SPDX-License-Identifier: GPL-2.0-only */
30 +
31 +#ifndef __ASM_SPECTRE_H
32 +#define __ASM_SPECTRE_H
33 +
34 +enum {
35 + SPECTRE_UNAFFECTED,
36 + SPECTRE_MITIGATED,
37 + SPECTRE_VULNERABLE,
38 +};
39 +
40 +enum {
41 + __SPECTRE_V2_METHOD_BPIALL,
42 + __SPECTRE_V2_METHOD_ICIALLU,
43 + __SPECTRE_V2_METHOD_SMC,
44 + __SPECTRE_V2_METHOD_HVC,
45 +};
46 +
47 +enum {
48 + SPECTRE_V2_METHOD_BPIALL = BIT(__SPECTRE_V2_METHOD_BPIALL),
49 + SPECTRE_V2_METHOD_ICIALLU = BIT(__SPECTRE_V2_METHOD_ICIALLU),
50 + SPECTRE_V2_METHOD_SMC = BIT(__SPECTRE_V2_METHOD_SMC),
51 + SPECTRE_V2_METHOD_HVC = BIT(__SPECTRE_V2_METHOD_HVC),
52 +};
53 +
54 +void spectre_v2_update_state(unsigned int state, unsigned int methods);
55 +
56 +#endif
57 --- a/arch/arm/kernel/Makefile
58 +++ b/arch/arm/kernel/Makefile
59 @@ -106,4 +106,6 @@ endif
60
61 obj-$(CONFIG_HAVE_ARM_SMCCC) += smccc-call.o
62
63 +obj-$(CONFIG_GENERIC_CPU_VULNERABILITIES) += spectre.o
64 +
65 extra-y := $(head-y) vmlinux.lds
66 --- /dev/null
67 +++ b/arch/arm/kernel/spectre.c
68 @@ -0,0 +1,54 @@
69 +// SPDX-License-Identifier: GPL-2.0-only
70 +#include <linux/cpu.h>
71 +#include <linux/device.h>
72 +
73 +#include <asm/spectre.h>
74 +
75 +ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr,
76 + char *buf)
77 +{
78 + return sprintf(buf, "Mitigation: __user pointer sanitization\n");
79 +}
80 +
81 +static unsigned int spectre_v2_state;
82 +static unsigned int spectre_v2_methods;
83 +
84 +void spectre_v2_update_state(unsigned int state, unsigned int method)
85 +{
86 + if (state > spectre_v2_state)
87 + spectre_v2_state = state;
88 + spectre_v2_methods |= method;
89 +}
90 +
91 +ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr,
92 + char *buf)
93 +{
94 + const char *method;
95 +
96 + if (spectre_v2_state == SPECTRE_UNAFFECTED)
97 + return sprintf(buf, "%s\n", "Not affected");
98 +
99 + if (spectre_v2_state != SPECTRE_MITIGATED)
100 + return sprintf(buf, "%s\n", "Vulnerable");
101 +
102 + switch (spectre_v2_methods) {
103 + case SPECTRE_V2_METHOD_BPIALL:
104 + method = "Branch predictor hardening";
105 + break;
106 +
107 + case SPECTRE_V2_METHOD_ICIALLU:
108 + method = "I-cache invalidation";
109 + break;
110 +
111 + case SPECTRE_V2_METHOD_SMC:
112 + case SPECTRE_V2_METHOD_HVC:
113 + method = "Firmware call";
114 + break;
115 +
116 + default:
117 + method = "Multiple mitigations";
118 + break;
119 + }
120 +
121 + return sprintf(buf, "Mitigation: %s\n", method);
122 +}
123 --- a/arch/arm/mm/Kconfig
124 +++ b/arch/arm/mm/Kconfig
125 @@ -830,6 +830,7 @@ config CPU_BPREDICT_DISABLE
126
127 config CPU_SPECTRE
128 bool
129 + select GENERIC_CPU_VULNERABILITIES
130
131 config HARDEN_BRANCH_PREDICTOR
132 bool "Harden the branch predictor against aliasing attacks" if EXPERT
133 --- a/arch/arm/mm/proc-v7-bugs.c
134 +++ b/arch/arm/mm/proc-v7-bugs.c
135 @@ -6,8 +6,35 @@
136 #include <asm/cp15.h>
137 #include <asm/cputype.h>
138 #include <asm/proc-fns.h>
139 +#include <asm/spectre.h>
140 #include <asm/system_misc.h>
141
142 +#ifdef CONFIG_ARM_PSCI
143 +static int __maybe_unused spectre_v2_get_cpu_fw_mitigation_state(void)
144 +{
145 + struct arm_smccc_res res;
146 +
147 + arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
148 + ARM_SMCCC_ARCH_WORKAROUND_1, &res);
149 +
150 + switch ((int)res.a0) {
151 + case SMCCC_RET_SUCCESS:
152 + return SPECTRE_MITIGATED;
153 +
154 + case SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED:
155 + return SPECTRE_UNAFFECTED;
156 +
157 + default:
158 + return SPECTRE_VULNERABLE;
159 + }
160 +}
161 +#else
162 +static int __maybe_unused spectre_v2_get_cpu_fw_mitigation_state(void)
163 +{
164 + return SPECTRE_VULNERABLE;
165 +}
166 +#endif
167 +
168 #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
169 DEFINE_PER_CPU(harden_branch_predictor_fn_t, harden_branch_predictor_fn);
170
171 @@ -36,13 +63,60 @@ static void __maybe_unused call_hvc_arch
172 arm_smccc_1_1_hvc(ARM_SMCCC_ARCH_WORKAROUND_1, NULL);
173 }
174
175 -static void cpu_v7_spectre_init(void)
176 +static unsigned int spectre_v2_install_workaround(unsigned int method)
177 {
178 const char *spectre_v2_method = NULL;
179 int cpu = smp_processor_id();
180
181 if (per_cpu(harden_branch_predictor_fn, cpu))
182 - return;
183 + return SPECTRE_MITIGATED;
184 +
185 + switch (method) {
186 + case SPECTRE_V2_METHOD_BPIALL:
187 + per_cpu(harden_branch_predictor_fn, cpu) =
188 + harden_branch_predictor_bpiall;
189 + spectre_v2_method = "BPIALL";
190 + break;
191 +
192 + case SPECTRE_V2_METHOD_ICIALLU:
193 + per_cpu(harden_branch_predictor_fn, cpu) =
194 + harden_branch_predictor_iciallu;
195 + spectre_v2_method = "ICIALLU";
196 + break;
197 +
198 + case SPECTRE_V2_METHOD_HVC:
199 + per_cpu(harden_branch_predictor_fn, cpu) =
200 + call_hvc_arch_workaround_1;
201 + cpu_do_switch_mm = cpu_v7_hvc_switch_mm;
202 + spectre_v2_method = "hypervisor";
203 + break;
204 +
205 + case SPECTRE_V2_METHOD_SMC:
206 + per_cpu(harden_branch_predictor_fn, cpu) =
207 + call_smc_arch_workaround_1;
208 + cpu_do_switch_mm = cpu_v7_smc_switch_mm;
209 + spectre_v2_method = "firmware";
210 + break;
211 + }
212 +
213 + if (spectre_v2_method)
214 + pr_info("CPU%u: Spectre v2: using %s workaround\n",
215 + smp_processor_id(), spectre_v2_method);
216 +
217 + return SPECTRE_MITIGATED;
218 +}
219 +#else
220 +static unsigned int spectre_v2_install_workaround(unsigned int method)
221 +{
222 + pr_info("CPU%u: Spectre V2: workarounds disabled by configuration\n");
223 +
224 + return SPECTRE_VULNERABLE;
225 +}
226 +#endif
227 +
228 +static void cpu_v7_spectre_v2_init(void)
229 +{
230 + unsigned int state, method = 0;
231
232 switch (read_cpuid_part()) {
233 case ARM_CPU_PART_CORTEX_A8:
234 @@ -51,68 +125,57 @@ static void cpu_v7_spectre_init(void)
235 case ARM_CPU_PART_CORTEX_A17:
236 case ARM_CPU_PART_CORTEX_A73:
237 case ARM_CPU_PART_CORTEX_A75:
238 - per_cpu(harden_branch_predictor_fn, cpu) =
239 - harden_branch_predictor_bpiall;
240 - spectre_v2_method = "BPIALL";
241 + state = SPECTRE_MITIGATED;
242 + method = SPECTRE_V2_METHOD_BPIALL;
243 break;
244
245 case ARM_CPU_PART_CORTEX_A15:
246 case ARM_CPU_PART_BRAHMA_B15:
247 - per_cpu(harden_branch_predictor_fn, cpu) =
248 - harden_branch_predictor_iciallu;
249 - spectre_v2_method = "ICIALLU";
250 + state = SPECTRE_MITIGATED;
251 + method = SPECTRE_V2_METHOD_ICIALLU;
252 break;
253
254 -#ifdef CONFIG_ARM_PSCI
255 case ARM_CPU_PART_BRAHMA_B53:
256 /* Requires no workaround */
257 + state = SPECTRE_UNAFFECTED;
258 break;
259 +
260 default:
261 /* Other ARM CPUs require no workaround */
262 - if (read_cpuid_implementor() == ARM_CPU_IMP_ARM)
263 + if (read_cpuid_implementor() == ARM_CPU_IMP_ARM) {
264 + state = SPECTRE_UNAFFECTED;
265 break;
266 + }
267 +
268 fallthrough;
269 - /* Cortex A57/A72 require firmware workaround */
270 - case ARM_CPU_PART_CORTEX_A57:
271 - case ARM_CPU_PART_CORTEX_A72: {
272 - struct arm_smccc_res res;
273
274 - arm_smccc_1_1_invoke(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
275 - ARM_SMCCC_ARCH_WORKAROUND_1, &res);
276 - if ((int)res.a0 != 0)
277 - return;
278 + /* Cortex A57/A72 require firmware workaround */
279 + case ARM_CPU_PART_CORTEX_A57:
280 + case ARM_CPU_PART_CORTEX_A72:
281 + state = spectre_v2_get_cpu_fw_mitigation_state();
282 + if (state != SPECTRE_MITIGATED)
283 + break;
284
285 switch (arm_smccc_1_1_get_conduit()) {
286 case SMCCC_CONDUIT_HVC:
287 - per_cpu(harden_branch_predictor_fn, cpu) =
288 - call_hvc_arch_workaround_1;
289 - cpu_do_switch_mm = cpu_v7_hvc_switch_mm;
290 - spectre_v2_method = "hypervisor";
291 + method = SPECTRE_V2_METHOD_HVC;
292 break;
293
294 case SMCCC_CONDUIT_SMC:
295 - per_cpu(harden_branch_predictor_fn, cpu) =
296 - call_smc_arch_workaround_1;
297 - cpu_do_switch_mm = cpu_v7_smc_switch_mm;
298 - spectre_v2_method = "firmware";
299 + method = SPECTRE_V2_METHOD_SMC;
300 break;
301
302 default:
303 + state = SPECTRE_VULNERABLE;
304 break;
305 }
306 }
307 -#endif
308 - }
309
310 - if (spectre_v2_method)
311 - pr_info("CPU%u: Spectre v2: using %s workaround\n",
312 - smp_processor_id(), spectre_v2_method);
313 -}
314 -#else
315 -static void cpu_v7_spectre_init(void)
316 -{
317 + if (state == SPECTRE_MITIGATED)
318 + state = spectre_v2_install_workaround(method);
319 +
320 + spectre_v2_update_state(state, method);
321 }
322 -#endif
323
324 static __maybe_unused bool cpu_v7_check_auxcr_set(bool *warned,
325 u32 mask, const char *msg)
326 @@ -142,16 +205,16 @@ static bool check_spectre_auxcr(bool *wa
327 void cpu_v7_ca8_ibe(void)
328 {
329 if (check_spectre_auxcr(this_cpu_ptr(&spectre_warned), BIT(6)))
330 - cpu_v7_spectre_init();
331 + cpu_v7_spectre_v2_init();
332 }
333
334 void cpu_v7_ca15_ibe(void)
335 {
336 if (check_spectre_auxcr(this_cpu_ptr(&spectre_warned), BIT(0)))
337 - cpu_v7_spectre_init();
338 + cpu_v7_spectre_v2_init();
339 }
340
341 void cpu_v7_bugs_init(void)
342 {
343 - cpu_v7_spectre_init();
344 + cpu_v7_spectre_v2_init();
345 }

  ViewVC Help
Powered by ViewVC 1.1.30