Skip to content

Commit

Permalink
x86/bugs: Enable STIBP for JMP2RET
Browse files Browse the repository at this point in the history
For untrained return thunks to be fully effective, STIBP must be enabled
or SMT disabled.

Co-developed-by: Josh Poimboeuf <[email protected]>
Signed-off-by: Josh Poimboeuf <[email protected]>
Signed-off-by: Kim Phillips <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Signed-off-by: Borislav Petkov <[email protected]>
  • Loading branch information
kimphillamd authored and suryasaimadhu committed Jun 27, 2022
1 parent 7fbf47c commit e8ec1b6
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 17 deletions.
16 changes: 11 additions & 5 deletions Documentation/admin-guide/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5201,11 +5201,17 @@
Speculative Code Execution with Return Instructions)
vulnerability.

off - unconditionally disable
auto - automatically select a migitation
unret - force enable untrained return thunks,
only effective on AMD Zen {1,2}
based systems.
off - no mitigation
auto - automatically select a migitation
auto,nosmt - automatically select a mitigation,
disabling SMT if necessary for
the full mitigation (only on Zen1
and older without STIBP).
unret - force enable untrained return thunks,
only effective on AMD f15h-f17h
based systems.
unret,nosmt - like unret, will disable SMT when STIBP
is not available.

Selecting 'auto' will choose a mitigation method at run
time according to the CPU.
Expand Down
58 changes: 46 additions & 12 deletions arch/x86/kernel/cpu/bugs.c
Original file line number Diff line number Diff line change
Expand Up @@ -783,19 +783,34 @@ static enum retbleed_mitigation retbleed_mitigation __ro_after_init =
static enum retbleed_mitigation_cmd retbleed_cmd __ro_after_init =
RETBLEED_CMD_AUTO;

static int __ro_after_init retbleed_nosmt = false;

static int __init retbleed_parse_cmdline(char *str)
{
if (!str)
return -EINVAL;

if (!strcmp(str, "off"))
retbleed_cmd = RETBLEED_CMD_OFF;
else if (!strcmp(str, "auto"))
retbleed_cmd = RETBLEED_CMD_AUTO;
else if (!strcmp(str, "unret"))
retbleed_cmd = RETBLEED_CMD_UNRET;
else
pr_err("Unknown retbleed option (%s). Defaulting to 'auto'\n", str);
while (str) {
char *next = strchr(str, ',');
if (next) {
*next = 0;
next++;
}

if (!strcmp(str, "off")) {
retbleed_cmd = RETBLEED_CMD_OFF;
} else if (!strcmp(str, "auto")) {
retbleed_cmd = RETBLEED_CMD_AUTO;
} else if (!strcmp(str, "unret")) {
retbleed_cmd = RETBLEED_CMD_UNRET;
} else if (!strcmp(str, "nosmt")) {
retbleed_nosmt = true;
} else {
pr_err("Ignoring unknown retbleed option (%s).", str);
}

str = next;
}

return 0;
}
Expand Down Expand Up @@ -841,6 +856,10 @@ static void __init retbleed_select_mitigation(void)
setup_force_cpu_cap(X86_FEATURE_RETHUNK);
setup_force_cpu_cap(X86_FEATURE_UNRET);

if (!boot_cpu_has(X86_FEATURE_STIBP) &&
(retbleed_nosmt || cpu_mitigations_auto_nosmt()))
cpu_smt_disable(false);

if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
pr_err(RETBLEED_UNTRAIN_MSG);
Expand Down Expand Up @@ -1087,6 +1106,13 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd)
boot_cpu_has(X86_FEATURE_AMD_STIBP_ALWAYS_ON))
mode = SPECTRE_V2_USER_STRICT_PREFERRED;

if (retbleed_mitigation == RETBLEED_MITIGATION_UNRET) {
if (mode != SPECTRE_V2_USER_STRICT &&
mode != SPECTRE_V2_USER_STRICT_PREFERRED)
pr_info("Selecting STIBP always-on mode to complement retbleed mitigation'\n");
mode = SPECTRE_V2_USER_STRICT_PREFERRED;
}

spectre_v2_user_stibp = mode;

set_mode:
Expand Down Expand Up @@ -2097,10 +2123,18 @@ static ssize_t srbds_show_state(char *buf)

static ssize_t retbleed_show_state(char *buf)
{
if (retbleed_mitigation == RETBLEED_MITIGATION_UNRET &&
(boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
boot_cpu_data.x86_vendor != X86_VENDOR_HYGON))
return sprintf(buf, "Vulnerable: untrained return thunk on non-Zen uarch\n");
if (retbleed_mitigation == RETBLEED_MITIGATION_UNRET) {
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
return sprintf(buf, "Vulnerable: untrained return thunk on non-Zen uarch\n");

return sprintf(buf, "%s; SMT %s\n",
retbleed_strings[retbleed_mitigation],
!sched_smt_active() ? "disabled" :
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT ||
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED ?
"enabled with STIBP protection" : "vulnerable");
}

return sprintf(buf, "%s\n", retbleed_strings[retbleed_mitigation]);
}
Expand Down

0 comments on commit e8ec1b6

Please sign in to comment.