x86/speculation: Enable prctl mode for spectre_v2_user

Now that all prerequisites are in place:

- Add the prctl command line option

- Default the 'auto' mode to 'prctl'

- When SMT state changes, update the static key which controls the
conditional STIBP evaluation on context switch.

- At init update the static key which controls the conditional IBPB
evaluation on context switch.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: David Woodhouse <dwmw@amazon.co.uk>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Casey Schaufler <casey.schaufler@intel.com>
Cc: Asit Mallick <asit.k.mallick@intel.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Jon Masters <jcm@redhat.com>
Cc: Waiman Long <longman9394@gmail.com>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: Dave Stewart <david.c.stewart@intel.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: stable@vger.kernel.org
Link: https://lkml.kernel.org/r/20181125185005.958421388@linutronix.de


+38 -10
+6 -1
Documentation/admin-guide/kernel-parameters.txt
··· 4236 4236 off - Unconditionally disable mitigations. Is 4237 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 4244 auto - Kernel selects the mitigation depending on 4240 4245 the available CPU features and vulnerability. 4241 - Default is off. 4246 + Default is prctl. 4242 4247 4243 4248 Not specifying this option is equivalent to 4244 4249 spectre_v2_user=auto.
+32 -9
arch/x86/kernel/cpu/bugs.c
··· 255 255 SPECTRE_V2_USER_CMD_NONE, 256 256 SPECTRE_V2_USER_CMD_AUTO, 257 257 SPECTRE_V2_USER_CMD_FORCE, 258 + SPECTRE_V2_USER_CMD_PRCTL, 258 259 }; 259 260 260 261 static const char * const spectre_v2_user_strings[] = { 261 262 [SPECTRE_V2_USER_NONE] = "User space: Vulnerable", 262 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 265 267 static const struct { ··· 272 270 { "auto", SPECTRE_V2_USER_CMD_AUTO, false }, 273 271 { "off", SPECTRE_V2_USER_CMD_NONE, false }, 274 272 { "on", SPECTRE_V2_USER_CMD_FORCE, true }, 273 + { "prctl", SPECTRE_V2_USER_CMD_PRCTL, false }, 275 274 }; 276 275 277 276 static void __init spec_v2_user_print_cond(const char *reason, bool secure) ··· 327 324 smt_possible = false; 328 325 329 326 switch (spectre_v2_parse_user_cmdline(v2_cmd)) { 330 - case SPECTRE_V2_USER_CMD_AUTO: 331 327 case SPECTRE_V2_USER_CMD_NONE: 332 328 goto set_mode; 333 329 case SPECTRE_V2_USER_CMD_FORCE: 334 330 mode = SPECTRE_V2_USER_STRICT; 331 + break; 332 + case SPECTRE_V2_USER_CMD_AUTO: 333 + case SPECTRE_V2_USER_CMD_PRCTL: 334 + mode = SPECTRE_V2_USER_PRCTL; 335 335 break; 336 336 } 337 337 ··· 345 339 switch (mode) { 346 340 case SPECTRE_V2_USER_STRICT: 347 341 static_branch_enable(&switch_mm_always_ibpb); 342 + break; 343 + case SPECTRE_V2_USER_PRCTL: 344 + static_branch_enable(&switch_mm_cond_ibpb); 348 345 break; 349 346 default: 350 347 break; ··· 361 352 if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) 362 353 return; 363 354 355 + /* 356 + * If SMT is not possible or STIBP is not available clear the STIPB 357 + * mode. 358 + */ 359 + if (!smt_possible || !boot_cpu_has(X86_FEATURE_STIBP)) 360 + mode = SPECTRE_V2_USER_NONE; 364 361 set_mode: 365 362 spectre_v2_user = mode; 366 363 /* Only print the STIBP mode when SMT possible */ ··· 567 552 on_each_cpu(update_stibp_msr, NULL, 1); 568 553 } 569 554 555 + /* Update the static key controlling the evaluation of TIF_SPEC_IB */ 556 + static void update_indir_branch_cond(void) 557 + { 558 + if (sched_smt_active()) 559 + static_branch_enable(&switch_to_cond_stibp); 560 + else 561 + static_branch_disable(&switch_to_cond_stibp); 562 + } 563 + 570 564 void arch_smt_update(void) 571 565 { 572 566 /* Enhanced IBRS implies STIBP. No update required. */ ··· 591 567 update_stibp_strict(); 592 568 break; 593 569 case SPECTRE_V2_USER_PRCTL: 570 + update_indir_branch_cond(); 594 571 break; 595 572 } 596 573 ··· 1063 1038 case SPECTRE_V2_USER_STRICT: 1064 1039 return ", STIBP: forced"; 1065 1040 case SPECTRE_V2_USER_PRCTL: 1066 - return ""; 1041 + if (static_key_enabled(&switch_to_cond_stibp)) 1042 + return ", STIBP: conditional"; 1067 1043 } 1068 1044 return ""; 1069 1045 } ··· 1072 1046 static char *ibpb_state(void) 1073 1047 { 1074 1048 if (boot_cpu_has(X86_FEATURE_IBPB)) { 1075 - switch (spectre_v2_user) { 1076 - case SPECTRE_V2_USER_NONE: 1077 - return ", IBPB: disabled"; 1078 - case SPECTRE_V2_USER_STRICT: 1049 + if (static_key_enabled(&switch_mm_always_ibpb)) 1079 1050 return ", IBPB: always-on"; 1080 - case SPECTRE_V2_USER_PRCTL: 1081 - return ""; 1082 - } 1051 + if (static_key_enabled(&switch_mm_cond_ibpb)) 1052 + return ", IBPB: conditional"; 1053 + return ", IBPB: disabled"; 1083 1054 } 1084 1055 return ""; 1085 1056 }