Skip to content

Commit 946175c

Browse files
author
Herton R. Krzesinski
committed
Merge: x86/bugs: Add late bug fixes to x86 speculation bugs
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/1550 Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2138389 This MR contains a number of late bug fixes to x86 speculation CVEs as well as a potential AMD microcode loading security bug. Signed-off-by: Waiman Long <longman@redhat.com> Approved-by: David Arcari <darcari@redhat.com> Approved-by: Lenny Szubowicz <lszubowi@redhat.com> Approved-by: Prarit Bhargava <prarit@redhat.com> Signed-off-by: Herton R. Krzesinski <herton@redhat.com>
2 parents befeafc + 7570d38 commit 946175c

File tree

6 files changed

+96
-34
lines changed

6 files changed

+96
-34
lines changed

Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,20 @@ The possible values in this file are:
230230
* - 'Mitigation: Clear CPU buffers'
231231
- The processor is vulnerable and the CPU buffer clearing mitigation is
232232
enabled.
233+
* - 'Unknown: No mitigations'
234+
- The processor vulnerability status is unknown because it is
235+
out of Servicing period. Mitigation is not attempted.
236+
237+
Definitions:
238+
------------
239+
240+
Servicing period: The process of providing functional and security updates to
241+
Intel processors or platforms, utilizing the Intel Platform Update (IPU)
242+
process or other similar mechanisms.
243+
244+
End of Servicing Updates (ESU): ESU is the date at which Intel will no
245+
longer provide Servicing, such as through IPU or other similar update
246+
processes. ESU dates will typically be aligned to end of quarter.
233247

234248
If the processor is vulnerable then the following information is appended to
235249
the above information:

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5127,20 +5127,33 @@
51275127
Speculative Code Execution with Return Instructions)
51285128
vulnerability.
51295129

5130+
AMD-based UNRET and IBPB mitigations alone do not stop
5131+
sibling threads from influencing the predictions of other
5132+
sibling threads. For that reason, STIBP is used on pro-
5133+
cessors that support it, and mitigate SMT on processors
5134+
that don't.
5135+
51305136
off - no mitigation
51315137
auto - automatically select a migitation
51325138
auto,nosmt - automatically select a mitigation,
51335139
disabling SMT if necessary for
51345140
the full mitigation (only on Zen1
51355141
and older without STIBP).
5136-
ibpb - mitigate short speculation windows on
5137-
basic block boundaries too. Safe, highest
5138-
perf impact.
5139-
unret - force enable untrained return thunks,
5140-
only effective on AMD f15h-f17h
5141-
based systems.
5142-
unret,nosmt - like unret, will disable SMT when STIBP
5143-
is not available.
5142+
ibpb - On AMD, mitigate short speculation
5143+
windows on basic block boundaries too.
5144+
Safe, highest perf impact. It also
5145+
enables STIBP if present. Not suitable
5146+
on Intel.
5147+
ibpb,nosmt - Like "ibpb" above but will disable SMT
5148+
when STIBP is not available. This is
5149+
the alternative for systems which do not
5150+
have STIBP.
5151+
unret - Force enable untrained return thunks,
5152+
only effective on AMD f15h-f17h based
5153+
systems.
5154+
unret,nosmt - Like unret, but will disable SMT when STIBP
5155+
is not available. This is the alternative for
5156+
systems which do not have STIBP.
51445157

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

arch/x86/include/asm/cpufeatures.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,8 @@
458458
#define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */
459459
#define X86_BUG_SRBDS X86_BUG(24) /* CPU may leak RNG bits if not mitigated */
460460
#define X86_BUG_MMIO_STALE_DATA X86_BUG(25) /* CPU is affected by Processor MMIO Stale Data vulnerabilities */
461-
#define X86_BUG_RETBLEED X86_BUG(26) /* CPU is affected by RETBleed */
462-
#define X86_BUG_EIBRS_PBRSB X86_BUG(27) /* EIBRS is vulnerable to Post Barrier RSB Predictions */
461+
#define X86_BUG_MMIO_UNKNOWN X86_BUG(26) /* CPU is too old and its MMIO Stale Data status is unknown */
462+
#define X86_BUG_RETBLEED X86_BUG(27) /* CPU is affected by RETBleed */
463+
#define X86_BUG_EIBRS_PBRSB X86_BUG(28) /* EIBRS is vulnerable to Post Barrier RSB Predictions */
463464

464465
#endif /* _ASM_X86_CPUFEATURES_H */

arch/x86/kernel/cpu/bugs.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ void __init check_bugs(void)
152152
/*
153153
* spectre_v2_user_select_mitigation() relies on the state set by
154154
* retbleed_select_mitigation(); specifically the STIBP selection is
155-
* forced for UNRET.
155+
* forced for UNRET or IBPB.
156156
*/
157157
spectre_v2_user_select_mitigation();
158158
ssb_select_mitigation();
@@ -433,7 +433,8 @@ static void __init mmio_select_mitigation(void)
433433
u64 ia32_cap;
434434

435435
if (!boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA) ||
436-
cpu_mitigations_off()) {
436+
boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN) ||
437+
cpu_mitigations_off()) {
437438
mmio_mitigation = MMIO_MITIGATION_OFF;
438439
return;
439440
}
@@ -538,6 +539,8 @@ static void __init md_clear_update_mitigation(void)
538539
pr_info("TAA: %s\n", taa_strings[taa_mitigation]);
539540
if (boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA))
540541
pr_info("MMIO Stale Data: %s\n", mmio_strings[mmio_mitigation]);
542+
else if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN))
543+
pr_info("MMIO Stale Data: Unknown: No mitigations\n");
541544
}
542545

543546
static void __init md_clear_select_mitigation(void)
@@ -1172,7 +1175,8 @@ spectre_v2_user_select_mitigation(void)
11721175
boot_cpu_has(X86_FEATURE_AMD_STIBP_ALWAYS_ON))
11731176
mode = SPECTRE_V2_USER_STRICT_PREFERRED;
11741177

1175-
if (retbleed_mitigation == RETBLEED_MITIGATION_UNRET) {
1178+
if (retbleed_mitigation == RETBLEED_MITIGATION_UNRET ||
1179+
retbleed_mitigation == RETBLEED_MITIGATION_IBPB) {
11761180
if (mode != SPECTRE_V2_USER_STRICT &&
11771181
mode != SPECTRE_V2_USER_STRICT_PREFERRED)
11781182
pr_info("Selecting STIBP always-on mode to complement retbleed mitigation\n");
@@ -2267,6 +2271,9 @@ static ssize_t tsx_async_abort_show_state(char *buf)
22672271

22682272
static ssize_t mmio_stale_data_show_state(char *buf)
22692273
{
2274+
if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN))
2275+
return sysfs_emit(buf, "Unknown: No mitigations\n");
2276+
22702277
if (mmio_mitigation == MMIO_MITIGATION_OFF)
22712278
return sysfs_emit(buf, "%s\n", mmio_strings[mmio_mitigation]);
22722279

@@ -2353,10 +2360,11 @@ static ssize_t srbds_show_state(char *buf)
23532360

23542361
static ssize_t retbleed_show_state(char *buf)
23552362
{
2356-
if (retbleed_mitigation == RETBLEED_MITIGATION_UNRET) {
2363+
if (retbleed_mitigation == RETBLEED_MITIGATION_UNRET ||
2364+
retbleed_mitigation == RETBLEED_MITIGATION_IBPB) {
23572365
if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
23582366
boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
2359-
return sprintf(buf, "Vulnerable: untrained return thunk on non-Zen uarch\n");
2367+
return sprintf(buf, "Vulnerable: untrained return thunk / IBPB on non-AMD based uarch\n");
23602368

23612369
return sprintf(buf, "%s; SMT %s\n",
23622370
retbleed_strings[retbleed_mitigation],
@@ -2412,6 +2420,7 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
24122420
return srbds_show_state(buf);
24132421

24142422
case X86_BUG_MMIO_STALE_DATA:
2423+
case X86_BUG_MMIO_UNKNOWN:
24152424
return mmio_stale_data_show_state(buf);
24162425

24172426
case X86_BUG_RETBLEED:
@@ -2471,7 +2480,10 @@ ssize_t cpu_show_srbds(struct device *dev, struct device_attribute *attr, char *
24712480

24722481
ssize_t cpu_show_mmio_stale_data(struct device *dev, struct device_attribute *attr, char *buf)
24732482
{
2474-
return cpu_show_common(dev, attr, buf, X86_BUG_MMIO_STALE_DATA);
2483+
if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN))
2484+
return cpu_show_common(dev, attr, buf, X86_BUG_MMIO_UNKNOWN);
2485+
else
2486+
return cpu_show_common(dev, attr, buf, X86_BUG_MMIO_STALE_DATA);
24752487
}
24762488

24772489
ssize_t cpu_show_retbleed(struct device *dev, struct device_attribute *attr, char *buf)

arch/x86/kernel/cpu/common.c

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,8 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
11601160
#define NO_SWAPGS BIT(6)
11611161
#define NO_ITLB_MULTIHIT BIT(7)
11621162
#define NO_SPECTRE_V2 BIT(8)
1163-
#define NO_EIBRS_PBRSB BIT(9)
1163+
#define NO_MMIO BIT(9)
1164+
#define NO_EIBRS_PBRSB BIT(10)
11641165

11651166
#define VULNWL(vendor, family, model, whitelist) \
11661167
X86_MATCH_VENDOR_FAM_MODEL(vendor, family, model, whitelist)
@@ -1181,6 +1182,11 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
11811182
VULNWL(NSC, 5, X86_MODEL_ANY, NO_SPECULATION),
11821183

11831184
/* Intel Family 6 */
1185+
VULNWL_INTEL(TIGERLAKE, NO_MMIO),
1186+
VULNWL_INTEL(TIGERLAKE_L, NO_MMIO),
1187+
VULNWL_INTEL(ALDERLAKE, NO_MMIO),
1188+
VULNWL_INTEL(ALDERLAKE_L, NO_MMIO),
1189+
11841190
VULNWL_INTEL(ATOM_SALTWELL, NO_SPECULATION | NO_ITLB_MULTIHIT),
11851191
VULNWL_INTEL(ATOM_SALTWELL_TABLET, NO_SPECULATION | NO_ITLB_MULTIHIT),
11861192
VULNWL_INTEL(ATOM_SALTWELL_MID, NO_SPECULATION | NO_ITLB_MULTIHIT),
@@ -1199,9 +1205,9 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
11991205
VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT),
12001206
VULNWL_INTEL(ATOM_AIRMONT_NP, NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT),
12011207

1202-
VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT),
1203-
VULNWL_INTEL(ATOM_GOLDMONT_D, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT),
1204-
VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_EIBRS_PBRSB),
1208+
VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
1209+
VULNWL_INTEL(ATOM_GOLDMONT_D, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
1210+
VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB),
12051211

12061212
/*
12071213
* Technically, swapgs isn't serializing on AMD (despite it previously
@@ -1216,18 +1222,18 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
12161222
VULNWL_INTEL(ATOM_TREMONT_D, NO_ITLB_MULTIHIT | NO_EIBRS_PBRSB),
12171223

12181224
/* AMD Family 0xf - 0x12 */
1219-
VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT),
1220-
VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT),
1221-
VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT),
1222-
VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT),
1225+
VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
1226+
VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
1227+
VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
1228+
VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
12231229

12241230
/* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */
1225-
VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT),
1226-
VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT),
1231+
VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
1232+
VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
12271233

12281234
/* Zhaoxin Family 7 */
1229-
VULNWL(CENTAUR, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS),
1230-
VULNWL(ZHAOXIN, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS),
1235+
VULNWL(CENTAUR, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO),
1236+
VULNWL(ZHAOXIN, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO),
12311237
{}
12321238
};
12331239

@@ -1381,10 +1387,16 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
13811387
* Affected CPU list is generally enough to enumerate the vulnerability,
13821388
* but for virtualization case check for ARCH_CAP MSR bits also, VMM may
13831389
* not want the guest to enumerate the bug.
1390+
*
1391+
* Set X86_BUG_MMIO_UNKNOWN for CPUs that are neither in the blacklist,
1392+
* nor in the whitelist and also don't enumerate MSR ARCH_CAP MMIO bits.
13841393
*/
1385-
if (cpu_matches(cpu_vuln_blacklist, MMIO) &&
1386-
!arch_cap_mmio_immune(ia32_cap))
1387-
setup_force_cpu_bug(X86_BUG_MMIO_STALE_DATA);
1394+
if (!arch_cap_mmio_immune(ia32_cap)) {
1395+
if (cpu_matches(cpu_vuln_blacklist, MMIO))
1396+
setup_force_cpu_bug(X86_BUG_MMIO_STALE_DATA);
1397+
else if (!cpu_matches(cpu_vuln_whitelist, NO_MMIO))
1398+
setup_force_cpu_bug(X86_BUG_MMIO_UNKNOWN);
1399+
}
13881400

13891401
if (!cpu_has(c, X86_FEATURE_BTC_NO)) {
13901402
if (cpu_matches(cpu_vuln_blacklist, RETBLEED) || (ia32_cap & ARCH_CAP_RSBA))

arch/x86/kernel/cpu/microcode/amd.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,13 @@ apply_microcode_early_amd(u32 cpuid_1_eax, void *ucode, size_t size, bool save_p
440440
return ret;
441441

442442
native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
443-
if (rev >= mc->hdr.patch_id)
443+
444+
/*
445+
* Allow application of the same revision to pick up SMT-specific
446+
* changes even if the revision of the other SMT thread is already
447+
* up-to-date.
448+
*/
449+
if (rev > mc->hdr.patch_id)
444450
return ret;
445451

446452
if (!__apply_microcode_amd(mc)) {
@@ -528,8 +534,12 @@ void load_ucode_amd_ap(unsigned int cpuid_1_eax)
528534

529535
native_rdmsr(MSR_AMD64_PATCH_LEVEL, rev, dummy);
530536

531-
/* Check whether we have saved a new patch already: */
532-
if (*new_rev && rev < mc->hdr.patch_id) {
537+
/*
538+
* Check whether a new patch has been saved already. Also, allow application of
539+
* the same revision in order to pick up SMT-thread-specific configuration even
540+
* if the sibling SMT thread already has an up-to-date revision.
541+
*/
542+
if (*new_rev && rev <= mc->hdr.patch_id) {
533543
if (!__apply_microcode_amd(mc)) {
534544
*new_rev = mc->hdr.patch_id;
535545
return;

0 commit comments

Comments
 (0)