]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.9/0037-x86-speculation-Add-command-line-control-for-indirec.patch
8ee0d8b214e39bc607f883f3b18093914560af47
[thirdparty/kernel/stable-queue.git] / queue-4.9 / 0037-x86-speculation-Add-command-line-control-for-indirec.patch
1 From 1e1b5239519c3deb3fc4b49d8e3c2975da5061f9 Mon Sep 17 00:00:00 2001
2 From: Thomas Gleixner <tglx@linutronix.de>
3 Date: Sun, 25 Nov 2018 19:33:45 +0100
4 Subject: [PATCH 37/76] x86/speculation: Add command line control for indirect
5 branch speculation
6
7 commit fa1202ef224391b6f5b26cdd44cc50495e8fab54 upstream.
8
9 Add command line control for user space indirect branch speculation
10 mitigations. The new option is: spectre_v2_user=
11
12 The initial options are:
13
14 - on: Unconditionally enabled
15 - off: Unconditionally disabled
16 -auto: Kernel selects mitigation (default off for now)
17
18 When the spectre_v2= command line argument is either 'on' or 'off' this
19 implies that the application to application control follows that state even
20 if a contradicting spectre_v2_user= argument is supplied.
21
22 Originally-by: Tim Chen <tim.c.chen@linux.intel.com>
23 Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
24 Reviewed-by: Ingo Molnar <mingo@kernel.org>
25 Cc: Peter Zijlstra <peterz@infradead.org>
26 Cc: Andy Lutomirski <luto@kernel.org>
27 Cc: Linus Torvalds <torvalds@linux-foundation.org>
28 Cc: Jiri Kosina <jkosina@suse.cz>
29 Cc: Tom Lendacky <thomas.lendacky@amd.com>
30 Cc: Josh Poimboeuf <jpoimboe@redhat.com>
31 Cc: Andrea Arcangeli <aarcange@redhat.com>
32 Cc: David Woodhouse <dwmw@amazon.co.uk>
33 Cc: Andi Kleen <ak@linux.intel.com>
34 Cc: Dave Hansen <dave.hansen@intel.com>
35 Cc: Casey Schaufler <casey.schaufler@intel.com>
36 Cc: Asit Mallick <asit.k.mallick@intel.com>
37 Cc: Arjan van de Ven <arjan@linux.intel.com>
38 Cc: Jon Masters <jcm@redhat.com>
39 Cc: Waiman Long <longman9394@gmail.com>
40 Cc: Greg KH <gregkh@linuxfoundation.org>
41 Cc: Dave Stewart <david.c.stewart@intel.com>
42 Cc: Kees Cook <keescook@chromium.org>
43 Link: https://lkml.kernel.org/r/20181125185005.082720373@linutronix.de
44 [bwh: Backported to 4.9: adjust filename]
45 Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
46 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
47 ---
48 Documentation/kernel-parameters.txt | 32 ++++++-
49 arch/x86/include/asm/nospec-branch.h | 10 ++
50 arch/x86/kernel/cpu/bugs.c | 133 +++++++++++++++++++++++----
51 3 files changed, 156 insertions(+), 19 deletions(-)
52
53 diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
54 index 18cfc4998481..cef2cb9cbf8a 100644
55 --- a/Documentation/kernel-parameters.txt
56 +++ b/Documentation/kernel-parameters.txt
57 @@ -4033,9 +4033,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
58
59 spectre_v2= [X86] Control mitigation of Spectre variant 2
60 (indirect branch speculation) vulnerability.
61 + The default operation protects the kernel from
62 + user space attacks.
63
64 - on - unconditionally enable
65 - off - unconditionally disable
66 + on - unconditionally enable, implies
67 + spectre_v2_user=on
68 + off - unconditionally disable, implies
69 + spectre_v2_user=off
70 auto - kernel detects whether your CPU model is
71 vulnerable
72
73 @@ -4045,6 +4049,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
74 CONFIG_RETPOLINE configuration option, and the
75 compiler with which the kernel was built.
76
77 + Selecting 'on' will also enable the mitigation
78 + against user space to user space task attacks.
79 +
80 + Selecting 'off' will disable both the kernel and
81 + the user space protections.
82 +
83 Specific mitigations can also be selected manually:
84
85 retpoline - replace indirect branches
86 @@ -4054,6 +4064,24 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
87 Not specifying this option is equivalent to
88 spectre_v2=auto.
89
90 + spectre_v2_user=
91 + [X86] Control mitigation of Spectre variant 2
92 + (indirect branch speculation) vulnerability between
93 + user space tasks
94 +
95 + on - Unconditionally enable mitigations. Is
96 + enforced by spectre_v2=on
97 +
98 + off - Unconditionally disable mitigations. Is
99 + enforced by spectre_v2=off
100 +
101 + auto - Kernel selects the mitigation depending on
102 + the available CPU features and vulnerability.
103 + Default is off.
104 +
105 + Not specifying this option is equivalent to
106 + spectre_v2_user=auto.
107 +
108 spec_store_bypass_disable=
109 [HW] Control Speculative Store Bypass (SSB) Disable mitigation
110 (Speculative Store Bypass vulnerability)
111 diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h
112 index d15c352db687..dab01da02de4 100644
113 --- a/arch/x86/include/asm/nospec-branch.h
114 +++ b/arch/x86/include/asm/nospec-branch.h
115 @@ -3,6 +3,8 @@
116 #ifndef _ASM_X86_NOSPEC_BRANCH_H_
117 #define _ASM_X86_NOSPEC_BRANCH_H_
118
119 +#include <linux/static_key.h>
120 +
121 #include <asm/alternative.h>
122 #include <asm/alternative-asm.h>
123 #include <asm/cpufeatures.h>
124 @@ -217,6 +219,12 @@ enum spectre_v2_mitigation {
125 SPECTRE_V2_IBRS_ENHANCED,
126 };
127
128 +/* The indirect branch speculation control variants */
129 +enum spectre_v2_user_mitigation {
130 + SPECTRE_V2_USER_NONE,
131 + SPECTRE_V2_USER_STRICT,
132 +};
133 +
134 /* The Speculative Store Bypass disable variants */
135 enum ssb_mitigation {
136 SPEC_STORE_BYPASS_NONE,
137 @@ -294,6 +302,8 @@ do { \
138 preempt_enable(); \
139 } while (0)
140
141 +DECLARE_STATIC_KEY_FALSE(switch_to_cond_stibp);
142 +
143 #endif /* __ASSEMBLY__ */
144
145 /*
146 diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
147 index cebaaa9f9424..8e414c416808 100644
148 --- a/arch/x86/kernel/cpu/bugs.c
149 +++ b/arch/x86/kernel/cpu/bugs.c
150 @@ -52,6 +52,9 @@ static u64 __ro_after_init x86_spec_ctrl_mask = SPEC_CTRL_IBRS;
151 u64 __ro_after_init x86_amd_ls_cfg_base;
152 u64 __ro_after_init x86_amd_ls_cfg_ssbd_mask;
153
154 +/* Control conditional STIPB in switch_to() */
155 +DEFINE_STATIC_KEY_FALSE(switch_to_cond_stibp);
156 +
157 void __init check_bugs(void)
158 {
159 identify_boot_cpu();
160 @@ -197,6 +200,9 @@ static void x86_amd_ssb_disable(void)
161 static enum spectre_v2_mitigation spectre_v2_enabled __ro_after_init =
162 SPECTRE_V2_NONE;
163
164 +static enum spectre_v2_user_mitigation spectre_v2_user __ro_after_init =
165 + SPECTRE_V2_USER_NONE;
166 +
167 #ifdef RETPOLINE
168 static bool spectre_v2_bad_module;
169
170 @@ -235,6 +241,104 @@ enum spectre_v2_mitigation_cmd {
171 SPECTRE_V2_CMD_RETPOLINE_AMD,
172 };
173
174 +enum spectre_v2_user_cmd {
175 + SPECTRE_V2_USER_CMD_NONE,
176 + SPECTRE_V2_USER_CMD_AUTO,
177 + SPECTRE_V2_USER_CMD_FORCE,
178 +};
179 +
180 +static const char * const spectre_v2_user_strings[] = {
181 + [SPECTRE_V2_USER_NONE] = "User space: Vulnerable",
182 + [SPECTRE_V2_USER_STRICT] = "User space: Mitigation: STIBP protection",
183 +};
184 +
185 +static const struct {
186 + const char *option;
187 + enum spectre_v2_user_cmd cmd;
188 + bool secure;
189 +} v2_user_options[] __initdata = {
190 + { "auto", SPECTRE_V2_USER_CMD_AUTO, false },
191 + { "off", SPECTRE_V2_USER_CMD_NONE, false },
192 + { "on", SPECTRE_V2_USER_CMD_FORCE, true },
193 +};
194 +
195 +static void __init spec_v2_user_print_cond(const char *reason, bool secure)
196 +{
197 + if (boot_cpu_has_bug(X86_BUG_SPECTRE_V2) != secure)
198 + pr_info("spectre_v2_user=%s forced on command line.\n", reason);
199 +}
200 +
201 +static enum spectre_v2_user_cmd __init
202 +spectre_v2_parse_user_cmdline(enum spectre_v2_mitigation_cmd v2_cmd)
203 +{
204 + char arg[20];
205 + int ret, i;
206 +
207 + switch (v2_cmd) {
208 + case SPECTRE_V2_CMD_NONE:
209 + return SPECTRE_V2_USER_CMD_NONE;
210 + case SPECTRE_V2_CMD_FORCE:
211 + return SPECTRE_V2_USER_CMD_FORCE;
212 + default:
213 + break;
214 + }
215 +
216 + ret = cmdline_find_option(boot_command_line, "spectre_v2_user",
217 + arg, sizeof(arg));
218 + if (ret < 0)
219 + return SPECTRE_V2_USER_CMD_AUTO;
220 +
221 + for (i = 0; i < ARRAY_SIZE(v2_user_options); i++) {
222 + if (match_option(arg, ret, v2_user_options[i].option)) {
223 + spec_v2_user_print_cond(v2_user_options[i].option,
224 + v2_user_options[i].secure);
225 + return v2_user_options[i].cmd;
226 + }
227 + }
228 +
229 + pr_err("Unknown user space protection option (%s). Switching to AUTO select\n", arg);
230 + return SPECTRE_V2_USER_CMD_AUTO;
231 +}
232 +
233 +static void __init
234 +spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd)
235 +{
236 + enum spectre_v2_user_mitigation mode = SPECTRE_V2_USER_NONE;
237 + bool smt_possible = IS_ENABLED(CONFIG_SMP);
238 +
239 + if (!boot_cpu_has(X86_FEATURE_IBPB) && !boot_cpu_has(X86_FEATURE_STIBP))
240 + return;
241 +
242 + if (cpu_smt_control == CPU_SMT_FORCE_DISABLED ||
243 + cpu_smt_control == CPU_SMT_NOT_SUPPORTED)
244 + smt_possible = false;
245 +
246 + switch (spectre_v2_parse_user_cmdline(v2_cmd)) {
247 + case SPECTRE_V2_USER_CMD_AUTO:
248 + case SPECTRE_V2_USER_CMD_NONE:
249 + goto set_mode;
250 + case SPECTRE_V2_USER_CMD_FORCE:
251 + mode = SPECTRE_V2_USER_STRICT;
252 + break;
253 + }
254 +
255 + /* Initialize Indirect Branch Prediction Barrier */
256 + if (boot_cpu_has(X86_FEATURE_IBPB)) {
257 + setup_force_cpu_cap(X86_FEATURE_USE_IBPB);
258 + pr_info("Spectre v2 mitigation: Enabling Indirect Branch Prediction Barrier\n");
259 + }
260 +
261 + /* If enhanced IBRS is enabled no STIPB required */
262 + if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED)
263 + return;
264 +
265 +set_mode:
266 + spectre_v2_user = mode;
267 + /* Only print the STIBP mode when SMT possible */
268 + if (smt_possible)
269 + pr_info("%s\n", spectre_v2_user_strings[mode]);
270 +}
271 +
272 static const char * const spectre_v2_strings[] = {
273 [SPECTRE_V2_NONE] = "Vulnerable",
274 [SPECTRE_V2_RETPOLINE_MINIMAL] = "Vulnerable: Minimal generic ASM retpoline",
275 @@ -390,12 +494,6 @@ static void __init spectre_v2_select_mitigation(void)
276 setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW);
277 pr_info("Spectre v2 / SpectreRSB mitigation: Filling RSB on context switch\n");
278
279 - /* Initialize Indirect Branch Prediction Barrier if supported */
280 - if (boot_cpu_has(X86_FEATURE_IBPB)) {
281 - setup_force_cpu_cap(X86_FEATURE_USE_IBPB);
282 - pr_info("Spectre v2 mitigation: Enabling Indirect Branch Prediction Barrier\n");
283 - }
284 -
285 /*
286 * Retpoline means the kernel is safe because it has no indirect
287 * branches. Enhanced IBRS protects firmware too, so, enable restricted
288 @@ -412,23 +510,21 @@ static void __init spectre_v2_select_mitigation(void)
289 pr_info("Enabling Restricted Speculation for firmware calls\n");
290 }
291
292 + /* Set up IBPB and STIBP depending on the general spectre V2 command */
293 + spectre_v2_user_select_mitigation(cmd);
294 +
295 /* Enable STIBP if appropriate */
296 arch_smt_update();
297 }
298
299 static bool stibp_needed(void)
300 {
301 - if (spectre_v2_enabled == SPECTRE_V2_NONE)
302 - return false;
303 -
304 /* Enhanced IBRS makes using STIBP unnecessary. */
305 if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED)
306 return false;
307
308 - if (!boot_cpu_has(X86_FEATURE_STIBP))
309 - return false;
310 -
311 - return true;
312 + /* Check for strict user mitigation mode */
313 + return spectre_v2_user == SPECTRE_V2_USER_STRICT;
314 }
315
316 static void update_stibp_msr(void *info)
317 @@ -850,10 +946,13 @@ static char *stibp_state(void)
318 if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED)
319 return "";
320
321 - if (x86_spec_ctrl_base & SPEC_CTRL_STIBP)
322 - return ", STIBP";
323 - else
324 - return "";
325 + switch (spectre_v2_user) {
326 + case SPECTRE_V2_USER_NONE:
327 + return ", STIBP: disabled";
328 + case SPECTRE_V2_USER_STRICT:
329 + return ", STIBP: forced";
330 + }
331 + return "";
332 }
333
334 static char *ibpb_state(void)
335 --
336 2.21.0
337