Skip to content

Commit 0eda20c

Browse files
pa1guptagregkh
authored andcommitted
x86/its: Enumerate Indirect Target Selection (ITS) bug
commit 159013a7ca18c271ff64192deb62a689b622d860 upstream. ITS bug in some pre-Alderlake Intel CPUs may allow indirect branches in the first half of a cache line get predicted to a target of a branch located in the second half of the cache line. Set X86_BUG_ITS on affected CPUs. Mitigation to follow in later commits. Signed-off-by: Pawan Gupta <[email protected]> Signed-off-by: Dave Hansen <[email protected]> Reviewed-by: Josh Poimboeuf <[email protected]> Reviewed-by: Alexandre Chartre <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent ed2e894 commit 0eda20c

File tree

4 files changed

+58
-13
lines changed

4 files changed

+58
-13
lines changed

arch/x86/include/asm/cpufeatures.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,4 +495,5 @@
495495
#define X86_BUG_RFDS X86_BUG(1*32 + 2) /* CPU is vulnerable to Register File Data Sampling */
496496
#define X86_BUG_BHI X86_BUG(1*32 + 3) /* CPU is affected by Branch History Injection */
497497
#define X86_BUG_IBPB_NO_RET X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB omits return target predictions */
498+
#define X86_BUG_ITS X86_BUG(1*32 + 5) /* CPU is affected by Indirect Target Selection */
498499
#endif /* _ASM_X86_CPUFEATURES_H */

arch/x86/include/asm/msr-index.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,14 @@
185185
* VERW clears CPU Register
186186
* File.
187187
*/
188+
#define ARCH_CAP_ITS_NO BIT_ULL(62) /*
189+
* Not susceptible to
190+
* Indirect Target Selection.
191+
* This bit is not set by
192+
* HW, but is synthesized by
193+
* VMMs for guests to know
194+
* their affected status.
195+
*/
188196

189197
#define ARCH_CAP_XAPIC_DISABLE BIT(21) /*
190198
* IA32_XAPIC_DISABLE_STATUS MSR

arch/x86/kernel/cpu/common.c

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,6 +1251,8 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
12511251
#define GDS BIT(6)
12521252
/* CPU is affected by Register File Data Sampling */
12531253
#define RFDS BIT(7)
1254+
/* CPU is affected by Indirect Target Selection */
1255+
#define ITS BIT(8)
12541256

12551257
static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
12561258
VULNBL_INTEL_STEPPINGS(IVYBRIDGE, X86_STEPPING_ANY, SRBDS),
@@ -1262,22 +1264,25 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
12621264
VULNBL_INTEL_STEPPINGS(BROADWELL_G, X86_STEPPING_ANY, SRBDS),
12631265
VULNBL_INTEL_STEPPINGS(BROADWELL_X, X86_STEPPING_ANY, MMIO),
12641266
VULNBL_INTEL_STEPPINGS(BROADWELL, X86_STEPPING_ANY, SRBDS),
1265-
VULNBL_INTEL_STEPPINGS(SKYLAKE_X, X86_STEPPING_ANY, MMIO | RETBLEED | GDS),
1267+
VULNBL_INTEL_STEPPINGS(SKYLAKE_X, X86_STEPPINGS(0x0, 0x5), MMIO | RETBLEED | GDS),
1268+
VULNBL_INTEL_STEPPINGS(SKYLAKE_X, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | ITS),
12661269
VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
12671270
VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
1268-
VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
1269-
VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
1271+
VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPINGS(0x0, 0xb), MMIO | RETBLEED | GDS | SRBDS),
1272+
VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS | ITS),
1273+
VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPINGS(0x0, 0xc), MMIO | RETBLEED | GDS | SRBDS),
1274+
VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS | ITS),
12701275
VULNBL_INTEL_STEPPINGS(CANNONLAKE_L, X86_STEPPING_ANY, RETBLEED),
1271-
VULNBL_INTEL_STEPPINGS(ICELAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS),
1272-
VULNBL_INTEL_STEPPINGS(ICELAKE_D, X86_STEPPING_ANY, MMIO | GDS),
1273-
VULNBL_INTEL_STEPPINGS(ICELAKE_X, X86_STEPPING_ANY, MMIO | GDS),
1274-
VULNBL_INTEL_STEPPINGS(COMETLAKE, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS),
1275-
VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPINGS(0x0, 0x0), MMIO | RETBLEED),
1276-
VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS),
1277-
VULNBL_INTEL_STEPPINGS(TIGERLAKE_L, X86_STEPPING_ANY, GDS),
1278-
VULNBL_INTEL_STEPPINGS(TIGERLAKE, X86_STEPPING_ANY, GDS),
1276+
VULNBL_INTEL_STEPPINGS(ICELAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
1277+
VULNBL_INTEL_STEPPINGS(ICELAKE_D, X86_STEPPING_ANY, MMIO | GDS | ITS),
1278+
VULNBL_INTEL_STEPPINGS(ICELAKE_X, X86_STEPPING_ANY, MMIO | GDS | ITS),
1279+
VULNBL_INTEL_STEPPINGS(COMETLAKE, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
1280+
VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPINGS(0x0, 0x0), MMIO | RETBLEED | ITS),
1281+
VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
1282+
VULNBL_INTEL_STEPPINGS(TIGERLAKE_L, X86_STEPPING_ANY, GDS | ITS),
1283+
VULNBL_INTEL_STEPPINGS(TIGERLAKE, X86_STEPPING_ANY, GDS | ITS),
12791284
VULNBL_INTEL_STEPPINGS(LAKEFIELD, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED),
1280-
VULNBL_INTEL_STEPPINGS(ROCKETLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS),
1285+
VULNBL_INTEL_STEPPINGS(ROCKETLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | ITS),
12811286
VULNBL_INTEL_STEPPINGS(ALDERLAKE, X86_STEPPING_ANY, RFDS),
12821287
VULNBL_INTEL_STEPPINGS(ALDERLAKE_L, X86_STEPPING_ANY, RFDS),
12831288
VULNBL_INTEL_STEPPINGS(RAPTORLAKE, X86_STEPPING_ANY, RFDS),
@@ -1341,6 +1346,32 @@ static bool __init vulnerable_to_rfds(u64 x86_arch_cap_msr)
13411346
return cpu_matches(cpu_vuln_blacklist, RFDS);
13421347
}
13431348

1349+
static bool __init vulnerable_to_its(u64 x86_arch_cap_msr)
1350+
{
1351+
/* The "immunity" bit trumps everything else: */
1352+
if (x86_arch_cap_msr & ARCH_CAP_ITS_NO)
1353+
return false;
1354+
if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
1355+
return false;
1356+
1357+
/* None of the affected CPUs have BHI_CTRL */
1358+
if (boot_cpu_has(X86_FEATURE_BHI_CTRL))
1359+
return false;
1360+
1361+
/*
1362+
* If a VMM did not expose ITS_NO, assume that a guest could
1363+
* be running on a vulnerable hardware or may migrate to such
1364+
* hardware.
1365+
*/
1366+
if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
1367+
return true;
1368+
1369+
if (cpu_matches(cpu_vuln_blacklist, ITS))
1370+
return true;
1371+
1372+
return false;
1373+
}
1374+
13441375
static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
13451376
{
13461377
u64 x86_arch_cap_msr = x86_read_arch_cap_msr();
@@ -1468,6 +1499,9 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
14681499
if (cpu_has(c, X86_FEATURE_AMD_IBPB) && !cpu_has(c, X86_FEATURE_AMD_IBPB_RET))
14691500
setup_force_cpu_bug(X86_BUG_IBPB_NO_RET);
14701501

1502+
if (vulnerable_to_its(x86_arch_cap_msr))
1503+
setup_force_cpu_bug(X86_BUG_ITS);
1504+
14711505
if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
14721506
return;
14731507

arch/x86/kvm/x86.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1614,7 +1614,7 @@ static unsigned int num_msr_based_features;
16141614
ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \
16151615
ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \
16161616
ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO | \
1617-
ARCH_CAP_RFDS_NO | ARCH_CAP_RFDS_CLEAR | ARCH_CAP_BHI_NO)
1617+
ARCH_CAP_RFDS_NO | ARCH_CAP_RFDS_CLEAR | ARCH_CAP_BHI_NO | ARCH_CAP_ITS_NO)
16181618

16191619
static u64 kvm_get_arch_capabilities(void)
16201620
{
@@ -1653,6 +1653,8 @@ static u64 kvm_get_arch_capabilities(void)
16531653
data |= ARCH_CAP_MDS_NO;
16541654
if (!boot_cpu_has_bug(X86_BUG_RFDS))
16551655
data |= ARCH_CAP_RFDS_NO;
1656+
if (!boot_cpu_has_bug(X86_BUG_ITS))
1657+
data |= ARCH_CAP_ITS_NO;
16561658

16571659
if (!boot_cpu_has(X86_FEATURE_RTM)) {
16581660
/*

0 commit comments

Comments
 (0)