@@ -54,6 +54,9 @@ static u64 __ro_after_init x86_spec_ctrl_mask = SPEC_CTRL_IBRS;
54
54
u64 __ro_after_init x86_amd_ls_cfg_base ;
55
55
u64 __ro_after_init x86_amd_ls_cfg_ssbd_mask ;
56
56
57
+ /* Control conditional STIPB in switch_to() */
58
+ DEFINE_STATIC_KEY_FALSE (switch_to_cond_stibp );
59
+
57
60
void __init check_bugs (void )
58
61
{
59
62
identify_boot_cpu ();
@@ -199,6 +202,9 @@ static void x86_amd_ssb_disable(void)
199
202
static enum spectre_v2_mitigation spectre_v2_enabled __ro_after_init =
200
203
SPECTRE_V2_NONE ;
201
204
205
+ static enum spectre_v2_user_mitigation spectre_v2_user __ro_after_init =
206
+ SPECTRE_V2_USER_NONE ;
207
+
202
208
#ifdef RETPOLINE
203
209
static bool spectre_v2_bad_module ;
204
210
@@ -237,6 +243,104 @@ enum spectre_v2_mitigation_cmd {
237
243
SPECTRE_V2_CMD_RETPOLINE_AMD ,
238
244
};
239
245
246
+ enum spectre_v2_user_cmd {
247
+ SPECTRE_V2_USER_CMD_NONE ,
248
+ SPECTRE_V2_USER_CMD_AUTO ,
249
+ SPECTRE_V2_USER_CMD_FORCE ,
250
+ };
251
+
252
+ static const char * const spectre_v2_user_strings [] = {
253
+ [SPECTRE_V2_USER_NONE ] = "User space: Vulnerable" ,
254
+ [SPECTRE_V2_USER_STRICT ] = "User space: Mitigation: STIBP protection" ,
255
+ };
256
+
257
+ static const struct {
258
+ const char * option ;
259
+ enum spectre_v2_user_cmd cmd ;
260
+ bool secure ;
261
+ } v2_user_options [] __initdata = {
262
+ { "auto" , SPECTRE_V2_USER_CMD_AUTO , false },
263
+ { "off" , SPECTRE_V2_USER_CMD_NONE , false },
264
+ { "on" , SPECTRE_V2_USER_CMD_FORCE , true },
265
+ };
266
+
267
+ static void __init spec_v2_user_print_cond (const char * reason , bool secure )
268
+ {
269
+ if (boot_cpu_has_bug (X86_BUG_SPECTRE_V2 ) != secure )
270
+ pr_info ("spectre_v2_user=%s forced on command line.\n" , reason );
271
+ }
272
+
273
+ static enum spectre_v2_user_cmd __init
274
+ spectre_v2_parse_user_cmdline (enum spectre_v2_mitigation_cmd v2_cmd )
275
+ {
276
+ char arg [20 ];
277
+ int ret , i ;
278
+
279
+ switch (v2_cmd ) {
280
+ case SPECTRE_V2_CMD_NONE :
281
+ return SPECTRE_V2_USER_CMD_NONE ;
282
+ case SPECTRE_V2_CMD_FORCE :
283
+ return SPECTRE_V2_USER_CMD_FORCE ;
284
+ default :
285
+ break ;
286
+ }
287
+
288
+ ret = cmdline_find_option (boot_command_line , "spectre_v2_user" ,
289
+ arg , sizeof (arg ));
290
+ if (ret < 0 )
291
+ return SPECTRE_V2_USER_CMD_AUTO ;
292
+
293
+ for (i = 0 ; i < ARRAY_SIZE (v2_user_options ); i ++ ) {
294
+ if (match_option (arg , ret , v2_user_options [i ].option )) {
295
+ spec_v2_user_print_cond (v2_user_options [i ].option ,
296
+ v2_user_options [i ].secure );
297
+ return v2_user_options [i ].cmd ;
298
+ }
299
+ }
300
+
301
+ pr_err ("Unknown user space protection option (%s). Switching to AUTO select\n" , arg );
302
+ return SPECTRE_V2_USER_CMD_AUTO ;
303
+ }
304
+
305
+ static void __init
306
+ spectre_v2_user_select_mitigation (enum spectre_v2_mitigation_cmd v2_cmd )
307
+ {
308
+ enum spectre_v2_user_mitigation mode = SPECTRE_V2_USER_NONE ;
309
+ bool smt_possible = IS_ENABLED (CONFIG_SMP );
310
+
311
+ if (!boot_cpu_has (X86_FEATURE_IBPB ) && !boot_cpu_has (X86_FEATURE_STIBP ))
312
+ return ;
313
+
314
+ if (cpu_smt_control == CPU_SMT_FORCE_DISABLED ||
315
+ cpu_smt_control == CPU_SMT_NOT_SUPPORTED )
316
+ smt_possible = false;
317
+
318
+ switch (spectre_v2_parse_user_cmdline (v2_cmd )) {
319
+ case SPECTRE_V2_USER_CMD_AUTO :
320
+ case SPECTRE_V2_USER_CMD_NONE :
321
+ goto set_mode ;
322
+ case SPECTRE_V2_USER_CMD_FORCE :
323
+ mode = SPECTRE_V2_USER_STRICT ;
324
+ break ;
325
+ }
326
+
327
+ /* Initialize Indirect Branch Prediction Barrier */
328
+ if (boot_cpu_has (X86_FEATURE_IBPB )) {
329
+ setup_force_cpu_cap (X86_FEATURE_USE_IBPB );
330
+ pr_info ("Spectre v2 mitigation: Enabling Indirect Branch Prediction Barrier\n" );
331
+ }
332
+
333
+ /* If enhanced IBRS is enabled no STIPB required */
334
+ if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED )
335
+ return ;
336
+
337
+ set_mode :
338
+ spectre_v2_user = mode ;
339
+ /* Only print the STIBP mode when SMT possible */
340
+ if (smt_possible )
341
+ pr_info ("%s\n" , spectre_v2_user_strings [mode ]);
342
+ }
343
+
240
344
static const char * const spectre_v2_strings [] = {
241
345
[SPECTRE_V2_NONE ] = "Vulnerable" ,
242
346
[SPECTRE_V2_RETPOLINE_GENERIC ] = "Mitigation: Full generic retpoline" ,
@@ -385,12 +489,6 @@ static void __init spectre_v2_select_mitigation(void)
385
489
setup_force_cpu_cap (X86_FEATURE_RSB_CTXSW );
386
490
pr_info ("Spectre v2 / SpectreRSB mitigation: Filling RSB on context switch\n" );
387
491
388
- /* Initialize Indirect Branch Prediction Barrier if supported */
389
- if (boot_cpu_has (X86_FEATURE_IBPB )) {
390
- setup_force_cpu_cap (X86_FEATURE_USE_IBPB );
391
- pr_info ("Spectre v2 mitigation: Enabling Indirect Branch Prediction Barrier\n" );
392
- }
393
-
394
492
/*
395
493
* Retpoline means the kernel is safe because it has no indirect
396
494
* branches. Enhanced IBRS protects firmware too, so, enable restricted
@@ -407,23 +505,21 @@ static void __init spectre_v2_select_mitigation(void)
407
505
pr_info ("Enabling Restricted Speculation for firmware calls\n" );
408
506
}
409
507
508
+ /* Set up IBPB and STIBP depending on the general spectre V2 command */
509
+ spectre_v2_user_select_mitigation (cmd );
510
+
410
511
/* Enable STIBP if appropriate */
411
512
arch_smt_update ();
412
513
}
413
514
414
515
static bool stibp_needed (void )
415
516
{
416
- if (spectre_v2_enabled == SPECTRE_V2_NONE )
417
- return false;
418
-
419
517
/* Enhanced IBRS makes using STIBP unnecessary. */
420
518
if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED )
421
519
return false;
422
520
423
- if (!boot_cpu_has (X86_FEATURE_STIBP ))
424
- return false;
425
-
426
- return true;
521
+ /* Check for strict user mitigation mode */
522
+ return spectre_v2_user == SPECTRE_V2_USER_STRICT ;
427
523
}
428
524
429
525
static void update_stibp_msr (void * info )
@@ -844,10 +940,13 @@ static char *stibp_state(void)
844
940
if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED )
845
941
return "" ;
846
942
847
- if (x86_spec_ctrl_base & SPEC_CTRL_STIBP )
848
- return ", STIBP" ;
849
- else
850
- return "" ;
943
+ switch (spectre_v2_user ) {
944
+ case SPECTRE_V2_USER_NONE :
945
+ return ", STIBP: disabled" ;
946
+ case SPECTRE_V2_USER_STRICT :
947
+ return ", STIBP: forced" ;
948
+ }
949
+ return "" ;
851
950
}
852
951
853
952
static char * ibpb_state (void )
0 commit comments