Skip to content

Commit e8ec1b6

Browse files
kimphillamdsuryasaimadhu
authored andcommitted
x86/bugs: Enable STIBP for JMP2RET
For untrained return thunks to be fully effective, STIBP must be enabled or SMT disabled. Co-developed-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Kim Phillips <kim.phillips@amd.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Borislav Petkov <bp@suse.de>
1 parent 7fbf47c commit e8ec1b6

2 files changed

Lines changed: 57 additions & 17 deletions

File tree

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5201,11 +5201,17 @@
52015201
Speculative Code Execution with Return Instructions)
52025202
vulnerability.
52035203

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

52105216
Selecting 'auto' will choose a mitigation method at run
52115217
time according to the CPU.

arch/x86/kernel/cpu/bugs.c

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -783,19 +783,34 @@ static enum retbleed_mitigation retbleed_mitigation __ro_after_init =
783783
static enum retbleed_mitigation_cmd retbleed_cmd __ro_after_init =
784784
RETBLEED_CMD_AUTO;
785785

786+
static int __ro_after_init retbleed_nosmt = false;
787+
786788
static int __init retbleed_parse_cmdline(char *str)
787789
{
788790
if (!str)
789791
return -EINVAL;
790792

791-
if (!strcmp(str, "off"))
792-
retbleed_cmd = RETBLEED_CMD_OFF;
793-
else if (!strcmp(str, "auto"))
794-
retbleed_cmd = RETBLEED_CMD_AUTO;
795-
else if (!strcmp(str, "unret"))
796-
retbleed_cmd = RETBLEED_CMD_UNRET;
797-
else
798-
pr_err("Unknown retbleed option (%s). Defaulting to 'auto'\n", str);
793+
while (str) {
794+
char *next = strchr(str, ',');
795+
if (next) {
796+
*next = 0;
797+
next++;
798+
}
799+
800+
if (!strcmp(str, "off")) {
801+
retbleed_cmd = RETBLEED_CMD_OFF;
802+
} else if (!strcmp(str, "auto")) {
803+
retbleed_cmd = RETBLEED_CMD_AUTO;
804+
} else if (!strcmp(str, "unret")) {
805+
retbleed_cmd = RETBLEED_CMD_UNRET;
806+
} else if (!strcmp(str, "nosmt")) {
807+
retbleed_nosmt = true;
808+
} else {
809+
pr_err("Ignoring unknown retbleed option (%s).", str);
810+
}
811+
812+
str = next;
813+
}
799814

800815
return 0;
801816
}
@@ -841,6 +856,10 @@ static void __init retbleed_select_mitigation(void)
841856
setup_force_cpu_cap(X86_FEATURE_RETHUNK);
842857
setup_force_cpu_cap(X86_FEATURE_UNRET);
843858

859+
if (!boot_cpu_has(X86_FEATURE_STIBP) &&
860+
(retbleed_nosmt || cpu_mitigations_auto_nosmt()))
861+
cpu_smt_disable(false);
862+
844863
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
845864
boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
846865
pr_err(RETBLEED_UNTRAIN_MSG);
@@ -1087,6 +1106,13 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd)
10871106
boot_cpu_has(X86_FEATURE_AMD_STIBP_ALWAYS_ON))
10881107
mode = SPECTRE_V2_USER_STRICT_PREFERRED;
10891108

1109+
if (retbleed_mitigation == RETBLEED_MITIGATION_UNRET) {
1110+
if (mode != SPECTRE_V2_USER_STRICT &&
1111+
mode != SPECTRE_V2_USER_STRICT_PREFERRED)
1112+
pr_info("Selecting STIBP always-on mode to complement retbleed mitigation'\n");
1113+
mode = SPECTRE_V2_USER_STRICT_PREFERRED;
1114+
}
1115+
10901116
spectre_v2_user_stibp = mode;
10911117

10921118
set_mode:
@@ -2097,10 +2123,18 @@ static ssize_t srbds_show_state(char *buf)
20972123

20982124
static ssize_t retbleed_show_state(char *buf)
20992125
{
2100-
if (retbleed_mitigation == RETBLEED_MITIGATION_UNRET &&
2101-
(boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
2102-
boot_cpu_data.x86_vendor != X86_VENDOR_HYGON))
2103-
return sprintf(buf, "Vulnerable: untrained return thunk on non-Zen uarch\n");
2126+
if (retbleed_mitigation == RETBLEED_MITIGATION_UNRET) {
2127+
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
2128+
boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
2129+
return sprintf(buf, "Vulnerable: untrained return thunk on non-Zen uarch\n");
2130+
2131+
return sprintf(buf, "%s; SMT %s\n",
2132+
retbleed_strings[retbleed_mitigation],
2133+
!sched_smt_active() ? "disabled" :
2134+
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT ||
2135+
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED ?
2136+
"enabled with STIBP protection" : "vulnerable");
2137+
}
21042138

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

0 commit comments

Comments
 (0)