History

x86/bugs: Enable STIBP for JMP2RET

For untrained return thunks to be fully effective, STIBP must be enabled or SMT disabled.

Kim Phillips committed 4 years ago

Commit e8ec1b61 parent 7fbf47c2 files · +57 −17Browse files

Unified · Split

2 files
  1. Documentation/admin-guide/kernel-parameters.txt +11 −5
  2. arch/x86/kernel/cpu/bugs.c +46 −12
Documentation/admin-guide/kernel-parameters.txt+11−5
@@ -5201,11 +5201,17 @@ · 5200 unmodified lines
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+46−12
@@ -783,19 +783,34 @@ static enum retbleed_mitigation retbleed_mitigation __ro_after_init = · 782 unmodified lines
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) · 39 unmodified lines
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) · 240 unmodified lines
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) · 1004 unmodified lines
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 }