aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/admin-guide/kernel-parameters.txt7
-rw-r--r--arch/x86/kernel/cpu/bugs.c41
2 files changed, 38 insertions, 10 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index b6e5b33b9d75..a9b98a4e8789 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -4236,9 +4236,14 @@
4236 off - Unconditionally disable mitigations. Is 4236 off - Unconditionally disable mitigations. Is
4237 enforced by spectre_v2=off 4237 enforced by spectre_v2=off
4238 4238
4239 prctl - Indirect branch speculation is enabled,
4240 but mitigation can be enabled via prctl
4241 per thread. The mitigation control state
4242 is inherited on fork.
4243
4239 auto - Kernel selects the mitigation depending on 4244 auto - Kernel selects the mitigation depending on
4240 the available CPU features and vulnerability. 4245 the available CPU features and vulnerability.
4241 Default is off. 4246 Default is prctl.
4242 4247
4243 Not specifying this option is equivalent to 4248 Not specifying this option is equivalent to
4244 spectre_v2_user=auto. 4249 spectre_v2_user=auto.
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 74359fff87fd..d0137d10f9a6 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -255,11 +255,13 @@ enum spectre_v2_user_cmd {
255 SPECTRE_V2_USER_CMD_NONE, 255 SPECTRE_V2_USER_CMD_NONE,
256 SPECTRE_V2_USER_CMD_AUTO, 256 SPECTRE_V2_USER_CMD_AUTO,
257 SPECTRE_V2_USER_CMD_FORCE, 257 SPECTRE_V2_USER_CMD_FORCE,
258 SPECTRE_V2_USER_CMD_PRCTL,
258}; 259};
259 260
260static const char * const spectre_v2_user_strings[] = { 261static const char * const spectre_v2_user_strings[] = {
261 [SPECTRE_V2_USER_NONE] = "User space: Vulnerable", 262 [SPECTRE_V2_USER_NONE] = "User space: Vulnerable",
262 [SPECTRE_V2_USER_STRICT] = "User space: Mitigation: STIBP protection", 263 [SPECTRE_V2_USER_STRICT] = "User space: Mitigation: STIBP protection",
264 [SPECTRE_V2_USER_PRCTL] = "User space: Mitigation: STIBP via prctl",
263}; 265};
264 266
265static const struct { 267static const struct {
@@ -270,6 +272,7 @@ static const struct {
270 { "auto", SPECTRE_V2_USER_CMD_AUTO, false }, 272 { "auto", SPECTRE_V2_USER_CMD_AUTO, false },
271 { "off", SPECTRE_V2_USER_CMD_NONE, false }, 273 { "off", SPECTRE_V2_USER_CMD_NONE, false },
272 { "on", SPECTRE_V2_USER_CMD_FORCE, true }, 274 { "on", SPECTRE_V2_USER_CMD_FORCE, true },
275 { "prctl", SPECTRE_V2_USER_CMD_PRCTL, false },
273}; 276};
274 277
275static void __init spec_v2_user_print_cond(const char *reason, bool secure) 278static void __init spec_v2_user_print_cond(const char *reason, bool secure)
@@ -324,12 +327,15 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd)
324 smt_possible = false; 327 smt_possible = false;
325 328
326 switch (spectre_v2_parse_user_cmdline(v2_cmd)) { 329 switch (spectre_v2_parse_user_cmdline(v2_cmd)) {
327 case SPECTRE_V2_USER_CMD_AUTO:
328 case SPECTRE_V2_USER_CMD_NONE: 330 case SPECTRE_V2_USER_CMD_NONE:
329 goto set_mode; 331 goto set_mode;
330 case SPECTRE_V2_USER_CMD_FORCE: 332 case SPECTRE_V2_USER_CMD_FORCE:
331 mode = SPECTRE_V2_USER_STRICT; 333 mode = SPECTRE_V2_USER_STRICT;
332 break; 334 break;
335 case SPECTRE_V2_USER_CMD_AUTO:
336 case SPECTRE_V2_USER_CMD_PRCTL:
337 mode = SPECTRE_V2_USER_PRCTL;
338 break;
333 } 339 }
334 340
335 /* Initialize Indirect Branch Prediction Barrier */ 341 /* Initialize Indirect Branch Prediction Barrier */
@@ -340,6 +346,9 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd)
340 case SPECTRE_V2_USER_STRICT: 346 case SPECTRE_V2_USER_STRICT:
341 static_branch_enable(&switch_mm_always_ibpb); 347 static_branch_enable(&switch_mm_always_ibpb);
342 break; 348 break;
349 case SPECTRE_V2_USER_PRCTL:
350 static_branch_enable(&switch_mm_cond_ibpb);
351 break;
343 default: 352 default:
344 break; 353 break;
345 } 354 }
@@ -352,6 +361,12 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd)
352 if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) 361 if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED)
353 return; 362 return;
354 363
364 /*
365 * If SMT is not possible or STIBP is not available clear the STIPB
366 * mode.
367 */
368 if (!smt_possible || !boot_cpu_has(X86_FEATURE_STIBP))
369 mode = SPECTRE_V2_USER_NONE;
355set_mode: 370set_mode:
356 spectre_v2_user = mode; 371 spectre_v2_user = mode;
357 /* Only print the STIBP mode when SMT possible */ 372 /* Only print the STIBP mode when SMT possible */
@@ -552,6 +567,15 @@ static void update_stibp_strict(void)
552 on_each_cpu(update_stibp_msr, NULL, 1); 567 on_each_cpu(update_stibp_msr, NULL, 1);
553} 568}
554 569
570/* Update the static key controlling the evaluation of TIF_SPEC_IB */
571static void update_indir_branch_cond(void)
572{
573 if (sched_smt_active())
574 static_branch_enable(&switch_to_cond_stibp);
575 else
576 static_branch_disable(&switch_to_cond_stibp);
577}
578
555void arch_smt_update(void) 579void arch_smt_update(void)
556{ 580{
557 /* Enhanced IBRS implies STIBP. No update required. */ 581 /* Enhanced IBRS implies STIBP. No update required. */
@@ -567,6 +591,7 @@ void arch_smt_update(void)
567 update_stibp_strict(); 591 update_stibp_strict();
568 break; 592 break;
569 case SPECTRE_V2_USER_PRCTL: 593 case SPECTRE_V2_USER_PRCTL:
594 update_indir_branch_cond();
570 break; 595 break;
571 } 596 }
572 597
@@ -1038,7 +1063,8 @@ static char *stibp_state(void)
1038 case SPECTRE_V2_USER_STRICT: 1063 case SPECTRE_V2_USER_STRICT:
1039 return ", STIBP: forced"; 1064 return ", STIBP: forced";
1040 case SPECTRE_V2_USER_PRCTL: 1065 case SPECTRE_V2_USER_PRCTL:
1041 return ""; 1066 if (static_key_enabled(&switch_to_cond_stibp))
1067 return ", STIBP: conditional";
1042 } 1068 }
1043 return ""; 1069 return "";
1044} 1070}
@@ -1046,14 +1072,11 @@ static char *stibp_state(void)
1046static char *ibpb_state(void) 1072static char *ibpb_state(void)
1047{ 1073{
1048 if (boot_cpu_has(X86_FEATURE_IBPB)) { 1074 if (boot_cpu_has(X86_FEATURE_IBPB)) {
1049 switch (spectre_v2_user) { 1075 if (static_key_enabled(&switch_mm_always_ibpb))
1050 case SPECTRE_V2_USER_NONE:
1051 return ", IBPB: disabled";
1052 case SPECTRE_V2_USER_STRICT:
1053 return ", IBPB: always-on"; 1076 return ", IBPB: always-on";
1054 case SPECTRE_V2_USER_PRCTL: 1077 if (static_key_enabled(&switch_mm_cond_ibpb))
1055 return ""; 1078 return ", IBPB: conditional";
1056 } 1079 return ", IBPB: disabled";
1057 } 1080 }
1058 return ""; 1081 return "";
1059} 1082}