Commit 7cc765a6 authored by Thomas Gleixner's avatar Thomas Gleixner

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: default avatarThomas Gleixner <tglx@linutronix.de>
Reviewed-by: default avatarIngo 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
parent 9137bb27
...@@ -4236,9 +4236,14 @@ ...@@ -4236,9 +4236,14 @@
off - Unconditionally disable mitigations. Is off - Unconditionally disable mitigations. Is
enforced by spectre_v2=off enforced by spectre_v2=off
prctl - Indirect branch speculation is enabled,
but mitigation can be enabled via prctl
per thread. The mitigation control state
is inherited on fork.
auto - Kernel selects the mitigation depending on auto - Kernel selects the mitigation depending on
the available CPU features and vulnerability. the available CPU features and vulnerability.
Default is off. Default is prctl.
Not specifying this option is equivalent to Not specifying this option is equivalent to
spectre_v2_user=auto. spectre_v2_user=auto.
......
...@@ -255,11 +255,13 @@ enum spectre_v2_user_cmd { ...@@ -255,11 +255,13 @@ enum spectre_v2_user_cmd {
SPECTRE_V2_USER_CMD_NONE, SPECTRE_V2_USER_CMD_NONE,
SPECTRE_V2_USER_CMD_AUTO, SPECTRE_V2_USER_CMD_AUTO,
SPECTRE_V2_USER_CMD_FORCE, SPECTRE_V2_USER_CMD_FORCE,
SPECTRE_V2_USER_CMD_PRCTL,
}; };
static const char * const spectre_v2_user_strings[] = { static const char * const spectre_v2_user_strings[] = {
[SPECTRE_V2_USER_NONE] = "User space: Vulnerable", [SPECTRE_V2_USER_NONE] = "User space: Vulnerable",
[SPECTRE_V2_USER_STRICT] = "User space: Mitigation: STIBP protection", [SPECTRE_V2_USER_STRICT] = "User space: Mitigation: STIBP protection",
[SPECTRE_V2_USER_PRCTL] = "User space: Mitigation: STIBP via prctl",
}; };
static const struct { static const struct {
...@@ -270,6 +272,7 @@ static const struct { ...@@ -270,6 +272,7 @@ static const struct {
{ "auto", SPECTRE_V2_USER_CMD_AUTO, false }, { "auto", SPECTRE_V2_USER_CMD_AUTO, false },
{ "off", SPECTRE_V2_USER_CMD_NONE, false }, { "off", SPECTRE_V2_USER_CMD_NONE, false },
{ "on", SPECTRE_V2_USER_CMD_FORCE, true }, { "on", SPECTRE_V2_USER_CMD_FORCE, true },
{ "prctl", SPECTRE_V2_USER_CMD_PRCTL, false },
}; };
static void __init spec_v2_user_print_cond(const char *reason, bool secure) static 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,12 +327,15 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd)
smt_possible = false; smt_possible = false;
switch (spectre_v2_parse_user_cmdline(v2_cmd)) { switch (spectre_v2_parse_user_cmdline(v2_cmd)) {
case SPECTRE_V2_USER_CMD_AUTO:
case SPECTRE_V2_USER_CMD_NONE: case SPECTRE_V2_USER_CMD_NONE:
goto set_mode; goto set_mode;
case SPECTRE_V2_USER_CMD_FORCE: case SPECTRE_V2_USER_CMD_FORCE:
mode = SPECTRE_V2_USER_STRICT; mode = SPECTRE_V2_USER_STRICT;
break; break;
case SPECTRE_V2_USER_CMD_AUTO:
case SPECTRE_V2_USER_CMD_PRCTL:
mode = SPECTRE_V2_USER_PRCTL;
break;
} }
/* Initialize Indirect Branch Prediction Barrier */ /* Initialize Indirect Branch Prediction Barrier */
...@@ -340,6 +346,9 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) ...@@ -340,6 +346,9 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd)
case SPECTRE_V2_USER_STRICT: case SPECTRE_V2_USER_STRICT:
static_branch_enable(&switch_mm_always_ibpb); static_branch_enable(&switch_mm_always_ibpb);
break; break;
case SPECTRE_V2_USER_PRCTL:
static_branch_enable(&switch_mm_cond_ibpb);
break;
default: default:
break; break;
} }
...@@ -352,6 +361,12 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) ...@@ -352,6 +361,12 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd)
if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED) if (spectre_v2_enabled == SPECTRE_V2_IBRS_ENHANCED)
return; return;
/*
* If SMT is not possible or STIBP is not available clear the STIPB
* mode.
*/
if (!smt_possible || !boot_cpu_has(X86_FEATURE_STIBP))
mode = SPECTRE_V2_USER_NONE;
set_mode: set_mode:
spectre_v2_user = mode; spectre_v2_user = mode;
/* Only print the STIBP mode when SMT possible */ /* Only print the STIBP mode when SMT possible */
...@@ -552,6 +567,15 @@ static void update_stibp_strict(void) ...@@ -552,6 +567,15 @@ static void update_stibp_strict(void)
on_each_cpu(update_stibp_msr, NULL, 1); on_each_cpu(update_stibp_msr, NULL, 1);
} }
/* Update the static key controlling the evaluation of TIF_SPEC_IB */
static void update_indir_branch_cond(void)
{
if (sched_smt_active())
static_branch_enable(&switch_to_cond_stibp);
else
static_branch_disable(&switch_to_cond_stibp);
}
void arch_smt_update(void) void arch_smt_update(void)
{ {
/* Enhanced IBRS implies STIBP. No update required. */ /* Enhanced IBRS implies STIBP. No update required. */
...@@ -567,6 +591,7 @@ void arch_smt_update(void) ...@@ -567,6 +591,7 @@ void arch_smt_update(void)
update_stibp_strict(); update_stibp_strict();
break; break;
case SPECTRE_V2_USER_PRCTL: case SPECTRE_V2_USER_PRCTL:
update_indir_branch_cond();
break; break;
} }
...@@ -1038,7 +1063,8 @@ static char *stibp_state(void) ...@@ -1038,7 +1063,8 @@ static char *stibp_state(void)
case SPECTRE_V2_USER_STRICT: case SPECTRE_V2_USER_STRICT:
return ", STIBP: forced"; return ", STIBP: forced";
case SPECTRE_V2_USER_PRCTL: case SPECTRE_V2_USER_PRCTL:
return ""; if (static_key_enabled(&switch_to_cond_stibp))
return ", STIBP: conditional";
} }
return ""; return "";
} }
...@@ -1046,14 +1072,11 @@ static char *stibp_state(void) ...@@ -1046,14 +1072,11 @@ static char *stibp_state(void)
static char *ibpb_state(void) static char *ibpb_state(void)
{ {
if (boot_cpu_has(X86_FEATURE_IBPB)) { if (boot_cpu_has(X86_FEATURE_IBPB)) {
switch (spectre_v2_user) { if (static_key_enabled(&switch_mm_always_ibpb))
case SPECTRE_V2_USER_NONE:
return ", IBPB: disabled";
case SPECTRE_V2_USER_STRICT:
return ", IBPB: always-on"; return ", IBPB: always-on";
case SPECTRE_V2_USER_PRCTL: if (static_key_enabled(&switch_mm_cond_ibpb))
return ""; return ", IBPB: conditional";
} return ", IBPB: disabled";
} }
return ""; return "";
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment