Commit e8ec1b6e authored by Kim Phillips's avatar Kim Phillips Committed by Borislav Petkov

x86/bugs: Enable STIBP for JMP2RET

For untrained return thunks to be fully effective, STIBP must be enabled
or SMT disabled.
Co-developed-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: default avatarKim Phillips <kim.phillips@amd.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
parent 7fbf47c7
...@@ -5201,11 +5201,17 @@ ...@@ -5201,11 +5201,17 @@
Speculative Code Execution with Return Instructions) Speculative Code Execution with Return Instructions)
vulnerability. vulnerability.
off - unconditionally disable off - no mitigation
auto - automatically select a migitation auto - automatically select a migitation
unret - force enable untrained return thunks, auto,nosmt - automatically select a mitigation,
only effective on AMD Zen {1,2} disabling SMT if necessary for
based systems. 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 Selecting 'auto' will choose a mitigation method at run
time according to the CPU. time according to the CPU.
......
...@@ -783,19 +783,34 @@ static enum retbleed_mitigation retbleed_mitigation __ro_after_init = ...@@ -783,19 +783,34 @@ static enum retbleed_mitigation retbleed_mitigation __ro_after_init =
static enum retbleed_mitigation_cmd retbleed_cmd __ro_after_init = static enum retbleed_mitigation_cmd retbleed_cmd __ro_after_init =
RETBLEED_CMD_AUTO; RETBLEED_CMD_AUTO;
static int __ro_after_init retbleed_nosmt = false;
static int __init retbleed_parse_cmdline(char *str) static int __init retbleed_parse_cmdline(char *str)
{ {
if (!str) if (!str)
return -EINVAL; return -EINVAL;
if (!strcmp(str, "off")) while (str) {
retbleed_cmd = RETBLEED_CMD_OFF; char *next = strchr(str, ',');
else if (!strcmp(str, "auto")) if (next) {
retbleed_cmd = RETBLEED_CMD_AUTO; *next = 0;
else if (!strcmp(str, "unret")) next++;
retbleed_cmd = RETBLEED_CMD_UNRET; }
else
pr_err("Unknown retbleed option (%s). Defaulting to 'auto'\n", str); 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; return 0;
} }
...@@ -841,6 +856,10 @@ static void __init retbleed_select_mitigation(void) ...@@ -841,6 +856,10 @@ static void __init retbleed_select_mitigation(void)
setup_force_cpu_cap(X86_FEATURE_RETHUNK); setup_force_cpu_cap(X86_FEATURE_RETHUNK);
setup_force_cpu_cap(X86_FEATURE_UNRET); 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 && if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
boot_cpu_data.x86_vendor != X86_VENDOR_HYGON) boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
pr_err(RETBLEED_UNTRAIN_MSG); pr_err(RETBLEED_UNTRAIN_MSG);
...@@ -1087,6 +1106,13 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) ...@@ -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)) boot_cpu_has(X86_FEATURE_AMD_STIBP_ALWAYS_ON))
mode = SPECTRE_V2_USER_STRICT_PREFERRED; 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; spectre_v2_user_stibp = mode;
set_mode: set_mode:
...@@ -2097,10 +2123,18 @@ static ssize_t srbds_show_state(char *buf) ...@@ -2097,10 +2123,18 @@ static ssize_t srbds_show_state(char *buf)
static ssize_t retbleed_show_state(char *buf) static ssize_t retbleed_show_state(char *buf)
{ {
if (retbleed_mitigation == RETBLEED_MITIGATION_UNRET && if (retbleed_mitigation == RETBLEED_MITIGATION_UNRET) {
(boot_cpu_data.x86_vendor != X86_VENDOR_AMD && if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)) boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
return sprintf(buf, "Vulnerable: untrained return thunk on non-Zen uarch\n"); 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]); return sprintf(buf, "%s\n", retbleed_strings[retbleed_mitigation]);
} }
......
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