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
5201 Speculative Code Execution with Return Instructions)5201 Speculative Code Execution with Return Instructions)
5202 vulnerability.5202 vulnerability.
5203 5203
5204 off - unconditionally disable5204 off - no mitigation
5205 auto - automatically select a migitation5205 auto - automatically select a migitation
5206 unret - force enable untrained return thunks,5206 auto,nosmt - automatically select a mitigation,
5207 only effective on AMD Zen {1,2}5207 disabling SMT if necessary for
5208 based systems.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.
5209 5215
5210 Selecting 'auto' will choose a mitigation method at run5216 Selecting 'auto' will choose a mitigation method at run
5211 time according to the CPU.5217 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
783static enum retbleed_mitigation_cmd retbleed_cmd __ro_after_init =783static enum retbleed_mitigation_cmd retbleed_cmd __ro_after_init =
784 RETBLEED_CMD_AUTO;784 RETBLEED_CMD_AUTO;
785 785
786static int __ro_after_init retbleed_nosmt = false;
787
786static int __init retbleed_parse_cmdline(char *str)788static int __init retbleed_parse_cmdline(char *str)
787{789{
788 if (!str)790 if (!str)
789 return -EINVAL;791 return -EINVAL;
790 792
791 if (!strcmp(str, "off"))793 while (str) {
792 retbleed_cmd = RETBLEED_CMD_OFF;794 char *next = strchr(str, ',');
793 else if (!strcmp(str, "auto"))795 if (next) {
794 retbleed_cmd = RETBLEED_CMD_AUTO;796 *next = 0;
795 else if (!strcmp(str, "unret"))797 next++;
796 retbleed_cmd = RETBLEED_CMD_UNRET;798 }
797 else799
798 pr_err("Unknown retbleed option (%s). Defaulting to 'auto'\n", str);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 }
799 814
800 return 0;815 return 0;
801}816}
@@ -841,6 +856,10 @@ static void __init retbleed_select_mitigation(void) · 39 unmodified lines
841 setup_force_cpu_cap(X86_FEATURE_RETHUNK);856 setup_force_cpu_cap(X86_FEATURE_RETHUNK);
842 setup_force_cpu_cap(X86_FEATURE_UNRET);857 setup_force_cpu_cap(X86_FEATURE_UNRET);
843 858
859 if (!boot_cpu_has(X86_FEATURE_STIBP) &&
860 (retbleed_nosmt || cpu_mitigations_auto_nosmt()))
861 cpu_smt_disable(false);
862
844 if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&863 if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
845 boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)864 boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
846 pr_err(RETBLEED_UNTRAIN_MSG);865 pr_err(RETBLEED_UNTRAIN_MSG);
@@ -1087,6 +1106,13 @@ spectre_v2_user_select_mitigation(enum spectre_v2_mitigation_cmd v2_cmd) · 240 unmodified lines
1087 boot_cpu_has(X86_FEATURE_AMD_STIBP_ALWAYS_ON))1106 boot_cpu_has(X86_FEATURE_AMD_STIBP_ALWAYS_ON))
1088 mode = SPECTRE_V2_USER_STRICT_PREFERRED;1107 mode = SPECTRE_V2_USER_STRICT_PREFERRED;
1089 1108
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
1090 spectre_v2_user_stibp = mode;1116 spectre_v2_user_stibp = mode;
1091 1117
1092set_mode:1118set_mode:
@@ -2097,10 +2123,18 @@ static ssize_t srbds_show_state(char *buf) · 1004 unmodified lines
2097 2123
2098static ssize_t retbleed_show_state(char *buf)2124static ssize_t retbleed_show_state(char *buf)
2099{2125{
2100 if (retbleed_mitigation == RETBLEED_MITIGATION_UNRET &&2126 if (retbleed_mitigation == RETBLEED_MITIGATION_UNRET) {
2101 (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&2127 if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
2102 boot_cpu_data.x86_vendor != X86_VENDOR_HYGON))2128 boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
2103 return sprintf(buf, "Vulnerable: untrained return thunk on non-Zen uarch\n");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 }
2104 2138
2105 return sprintf(buf, "%s\n", retbleed_strings[retbleed_mitigation]);2139 return sprintf(buf, "%s\n", retbleed_strings[retbleed_mitigation]);
2106}2140}