Skip to content

Commit 159013a

Browse files
pa1guptahansendc
authored andcommitted
x86/its: Enumerate Indirect Target Selection (ITS) bug
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]>
1 parent 1ac116c commit 159013a

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
@@ -533,4 +533,5 @@
533533
#define X86_BUG_BHI X86_BUG(1*32 + 3) /* "bhi" CPU is affected by Branch History Injection */
534534
#define X86_BUG_IBPB_NO_RET X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB omits return target predictions */
535535
#define X86_BUG_SPECTRE_V2_USER X86_BUG(1*32 + 5) /* "spectre_v2_user" CPU is affected by Spectre variant 2 attack between user processes */
536+
#define X86_BUG_ITS X86_BUG(1*32 + 6) /* "its" CPU is affected by Indirect Target Selection */
536537
#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
@@ -211,6 +211,14 @@
211211
* VERW clears CPU Register
212212
* File.
213213
*/
214+
#define ARCH_CAP_ITS_NO BIT_ULL(62) /*
215+
* Not susceptible to
216+
* Indirect Target Selection.
217+
* This bit is not set by
218+
* HW, but is synthesized by
219+
* VMMs for guests to know
220+
* their affected status.
221+
*/
214222

215223
#define MSR_IA32_FLUSH_CMD 0x0000010b
216224
#define L1D_FLUSH BIT(0) /*

arch/x86/kernel/cpu/common.c

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,6 +1227,8 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
12271227
#define GDS BIT(6)
12281228
/* CPU is affected by Register File Data Sampling */
12291229
#define RFDS BIT(7)
1230+
/* CPU is affected by Indirect Target Selection */
1231+
#define ITS BIT(8)
12301232

12311233
static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
12321234
VULNBL_INTEL_STEPS(INTEL_IVYBRIDGE, X86_STEP_MAX, SRBDS),
@@ -1238,22 +1240,25 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
12381240
VULNBL_INTEL_STEPS(INTEL_BROADWELL_G, X86_STEP_MAX, SRBDS),
12391241
VULNBL_INTEL_STEPS(INTEL_BROADWELL_X, X86_STEP_MAX, MMIO),
12401242
VULNBL_INTEL_STEPS(INTEL_BROADWELL, X86_STEP_MAX, SRBDS),
1241-
VULNBL_INTEL_STEPS(INTEL_SKYLAKE_X, X86_STEP_MAX, MMIO | RETBLEED | GDS),
1243+
VULNBL_INTEL_STEPS(INTEL_SKYLAKE_X, 0x5, MMIO | RETBLEED | GDS),
1244+
VULNBL_INTEL_STEPS(INTEL_SKYLAKE_X, X86_STEP_MAX, MMIO | RETBLEED | GDS | ITS),
12421245
VULNBL_INTEL_STEPS(INTEL_SKYLAKE_L, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS),
12431246
VULNBL_INTEL_STEPS(INTEL_SKYLAKE, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS),
1244-
VULNBL_INTEL_STEPS(INTEL_KABYLAKE_L, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS),
1245-
VULNBL_INTEL_STEPS(INTEL_KABYLAKE, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS),
1247+
VULNBL_INTEL_STEPS(INTEL_KABYLAKE_L, 0xb, MMIO | RETBLEED | GDS | SRBDS),
1248+
VULNBL_INTEL_STEPS(INTEL_KABYLAKE_L, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS | ITS),
1249+
VULNBL_INTEL_STEPS(INTEL_KABYLAKE, 0xc, MMIO | RETBLEED | GDS | SRBDS),
1250+
VULNBL_INTEL_STEPS(INTEL_KABYLAKE, X86_STEP_MAX, MMIO | RETBLEED | GDS | SRBDS | ITS),
12461251
VULNBL_INTEL_STEPS(INTEL_CANNONLAKE_L, X86_STEP_MAX, RETBLEED),
1247-
VULNBL_INTEL_STEPS(INTEL_ICELAKE_L, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS),
1248-
VULNBL_INTEL_STEPS(INTEL_ICELAKE_D, X86_STEP_MAX, MMIO | GDS),
1249-
VULNBL_INTEL_STEPS(INTEL_ICELAKE_X, X86_STEP_MAX, MMIO | GDS),
1250-
VULNBL_INTEL_STEPS(INTEL_COMETLAKE, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS),
1251-
VULNBL_INTEL_STEPS(INTEL_COMETLAKE_L, 0x0, MMIO | RETBLEED),
1252-
VULNBL_INTEL_STEPS(INTEL_COMETLAKE_L, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS),
1253-
VULNBL_INTEL_STEPS(INTEL_TIGERLAKE_L, X86_STEP_MAX, GDS),
1254-
VULNBL_INTEL_STEPS(INTEL_TIGERLAKE, X86_STEP_MAX, GDS),
1252+
VULNBL_INTEL_STEPS(INTEL_ICELAKE_L, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
1253+
VULNBL_INTEL_STEPS(INTEL_ICELAKE_D, X86_STEP_MAX, MMIO | GDS | ITS),
1254+
VULNBL_INTEL_STEPS(INTEL_ICELAKE_X, X86_STEP_MAX, MMIO | GDS | ITS),
1255+
VULNBL_INTEL_STEPS(INTEL_COMETLAKE, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
1256+
VULNBL_INTEL_STEPS(INTEL_COMETLAKE_L, 0x0, MMIO | RETBLEED | ITS),
1257+
VULNBL_INTEL_STEPS(INTEL_COMETLAKE_L, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
1258+
VULNBL_INTEL_STEPS(INTEL_TIGERLAKE_L, X86_STEP_MAX, GDS | ITS),
1259+
VULNBL_INTEL_STEPS(INTEL_TIGERLAKE, X86_STEP_MAX, GDS | ITS),
12551260
VULNBL_INTEL_STEPS(INTEL_LAKEFIELD, X86_STEP_MAX, MMIO | MMIO_SBDS | RETBLEED),
1256-
VULNBL_INTEL_STEPS(INTEL_ROCKETLAKE, X86_STEP_MAX, MMIO | RETBLEED | GDS),
1261+
VULNBL_INTEL_STEPS(INTEL_ROCKETLAKE, X86_STEP_MAX, MMIO | RETBLEED | GDS | ITS),
12571262
VULNBL_INTEL_TYPE(INTEL_ALDERLAKE, ATOM, RFDS),
12581263
VULNBL_INTEL_STEPS(INTEL_ALDERLAKE_L, X86_STEP_MAX, RFDS),
12591264
VULNBL_INTEL_TYPE(INTEL_RAPTORLAKE, ATOM, RFDS),
@@ -1318,6 +1323,32 @@ static bool __init vulnerable_to_rfds(u64 x86_arch_cap_msr)
13181323
return cpu_matches(cpu_vuln_blacklist, RFDS);
13191324
}
13201325

1326+
static bool __init vulnerable_to_its(u64 x86_arch_cap_msr)
1327+
{
1328+
/* The "immunity" bit trumps everything else: */
1329+
if (x86_arch_cap_msr & ARCH_CAP_ITS_NO)
1330+
return false;
1331+
if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
1332+
return false;
1333+
1334+
/* None of the affected CPUs have BHI_CTRL */
1335+
if (boot_cpu_has(X86_FEATURE_BHI_CTRL))
1336+
return false;
1337+
1338+
/*
1339+
* If a VMM did not expose ITS_NO, assume that a guest could
1340+
* be running on a vulnerable hardware or may migrate to such
1341+
* hardware.
1342+
*/
1343+
if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
1344+
return true;
1345+
1346+
if (cpu_matches(cpu_vuln_blacklist, ITS))
1347+
return true;
1348+
1349+
return false;
1350+
}
1351+
13211352
static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
13221353
{
13231354
u64 x86_arch_cap_msr = x86_read_arch_cap_msr();
@@ -1449,6 +1480,9 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
14491480
if (cpu_has(c, X86_FEATURE_AMD_IBPB) && !cpu_has(c, X86_FEATURE_AMD_IBPB_RET))
14501481
setup_force_cpu_bug(X86_BUG_IBPB_NO_RET);
14511482

1483+
if (vulnerable_to_its(x86_arch_cap_msr))
1484+
setup_force_cpu_bug(X86_BUG_ITS);
1485+
14521486
if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
14531487
return;
14541488

arch/x86/kvm/x86.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1584,7 +1584,7 @@ EXPORT_SYMBOL_GPL(kvm_emulate_rdpmc);
15841584
ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \
15851585
ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \
15861586
ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO | \
1587-
ARCH_CAP_RFDS_NO | ARCH_CAP_RFDS_CLEAR | ARCH_CAP_BHI_NO)
1587+
ARCH_CAP_RFDS_NO | ARCH_CAP_RFDS_CLEAR | ARCH_CAP_BHI_NO | ARCH_CAP_ITS_NO)
15881588

15891589
static u64 kvm_get_arch_capabilities(void)
15901590
{
@@ -1618,6 +1618,8 @@ static u64 kvm_get_arch_capabilities(void)
16181618
data |= ARCH_CAP_MDS_NO;
16191619
if (!boot_cpu_has_bug(X86_BUG_RFDS))
16201620
data |= ARCH_CAP_RFDS_NO;
1621+
if (!boot_cpu_has_bug(X86_BUG_ITS))
1622+
data |= ARCH_CAP_ITS_NO;
16211623

16221624
if (!boot_cpu_has(X86_FEATURE_RTM)) {
16231625
/*

0 commit comments

Comments
 (0)