Skip to content

Commit a6f2a43

Browse files
pa1guptagregkh
authored andcommitted
x86/its: Enumerate Indirect Target Selection (ITS) bug
commit 159013a 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 76f8476 commit a6f2a43

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
@@ -526,4 +526,5 @@
526526
#define X86_BUG_RFDS X86_BUG(1*32 + 2) /* "rfds" CPU is vulnerable to Register File Data Sampling */
527527
#define X86_BUG_BHI X86_BUG(1*32 + 3) /* "bhi" CPU is affected by Branch History Injection */
528528
#define X86_BUG_IBPB_NO_RET X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB omits return target predictions */
529+
#define X86_BUG_ITS X86_BUG(1*32 + 5) /* "its" CPU is affected by Indirect Target Selection */
529530
#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
@@ -209,6 +209,14 @@
209209
* VERW clears CPU Register
210210
* File.
211211
*/
212+
#define ARCH_CAP_ITS_NO BIT_ULL(62) /*
213+
* Not susceptible to
214+
* Indirect Target Selection.
215+
* This bit is not set by
216+
* HW, but is synthesized by
217+
* VMMs for guests to know
218+
* their affected status.
219+
*/
212220

213221
#define MSR_IA32_FLUSH_CMD 0x0000010b
214222
#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
@@ -1228,6 +1228,8 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
12281228
#define GDS BIT(6)
12291229
/* CPU is affected by Register File Data Sampling */
12301230
#define RFDS BIT(7)
1231+
/* CPU is affected by Indirect Target Selection */
1232+
#define ITS BIT(8)
12311233

12321234
static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
12331235
VULNBL_INTEL_STEPPINGS(INTEL_IVYBRIDGE, X86_STEPPING_ANY, SRBDS),
@@ -1239,22 +1241,25 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
12391241
VULNBL_INTEL_STEPPINGS(INTEL_BROADWELL_G, X86_STEPPING_ANY, SRBDS),
12401242
VULNBL_INTEL_STEPPINGS(INTEL_BROADWELL_X, X86_STEPPING_ANY, MMIO),
12411243
VULNBL_INTEL_STEPPINGS(INTEL_BROADWELL, X86_STEPPING_ANY, SRBDS),
1242-
VULNBL_INTEL_STEPPINGS(INTEL_SKYLAKE_X, X86_STEPPING_ANY, MMIO | RETBLEED | GDS),
1244+
VULNBL_INTEL_STEPPINGS(INTEL_SKYLAKE_X, X86_STEPPINGS(0x0, 0x5), MMIO | RETBLEED | GDS),
1245+
VULNBL_INTEL_STEPPINGS(INTEL_SKYLAKE_X, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | ITS),
12431246
VULNBL_INTEL_STEPPINGS(INTEL_SKYLAKE_L, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
12441247
VULNBL_INTEL_STEPPINGS(INTEL_SKYLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
1245-
VULNBL_INTEL_STEPPINGS(INTEL_KABYLAKE_L, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
1246-
VULNBL_INTEL_STEPPINGS(INTEL_KABYLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS),
1248+
VULNBL_INTEL_STEPPINGS(INTEL_KABYLAKE_L, X86_STEPPINGS(0x0, 0xb), MMIO | RETBLEED | GDS | SRBDS),
1249+
VULNBL_INTEL_STEPPINGS(INTEL_KABYLAKE_L, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS | ITS),
1250+
VULNBL_INTEL_STEPPINGS(INTEL_KABYLAKE, X86_STEPPINGS(0x0, 0xc), MMIO | RETBLEED | GDS | SRBDS),
1251+
VULNBL_INTEL_STEPPINGS(INTEL_KABYLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS | ITS),
12471252
VULNBL_INTEL_STEPPINGS(INTEL_CANNONLAKE_L, X86_STEPPING_ANY, RETBLEED),
1248-
VULNBL_INTEL_STEPPINGS(INTEL_ICELAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS),
1249-
VULNBL_INTEL_STEPPINGS(INTEL_ICELAKE_D, X86_STEPPING_ANY, MMIO | GDS),
1250-
VULNBL_INTEL_STEPPINGS(INTEL_ICELAKE_X, X86_STEPPING_ANY, MMIO | GDS),
1251-
VULNBL_INTEL_STEPPINGS(INTEL_COMETLAKE, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS),
1252-
VULNBL_INTEL_STEPPINGS(INTEL_COMETLAKE_L, X86_STEPPINGS(0x0, 0x0), MMIO | RETBLEED),
1253-
VULNBL_INTEL_STEPPINGS(INTEL_COMETLAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS),
1254-
VULNBL_INTEL_STEPPINGS(INTEL_TIGERLAKE_L, X86_STEPPING_ANY, GDS),
1255-
VULNBL_INTEL_STEPPINGS(INTEL_TIGERLAKE, X86_STEPPING_ANY, GDS),
1253+
VULNBL_INTEL_STEPPINGS(INTEL_ICELAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
1254+
VULNBL_INTEL_STEPPINGS(INTEL_ICELAKE_D, X86_STEPPING_ANY, MMIO | GDS | ITS),
1255+
VULNBL_INTEL_STEPPINGS(INTEL_ICELAKE_X, X86_STEPPING_ANY, MMIO | GDS | ITS),
1256+
VULNBL_INTEL_STEPPINGS(INTEL_COMETLAKE, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
1257+
VULNBL_INTEL_STEPPINGS(INTEL_COMETLAKE_L, X86_STEPPINGS(0x0, 0x0), MMIO | RETBLEED | ITS),
1258+
VULNBL_INTEL_STEPPINGS(INTEL_COMETLAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
1259+
VULNBL_INTEL_STEPPINGS(INTEL_TIGERLAKE_L, X86_STEPPING_ANY, GDS | ITS),
1260+
VULNBL_INTEL_STEPPINGS(INTEL_TIGERLAKE, X86_STEPPING_ANY, GDS | ITS),
12561261
VULNBL_INTEL_STEPPINGS(INTEL_LAKEFIELD, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED),
1257-
VULNBL_INTEL_STEPPINGS(INTEL_ROCKETLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS),
1262+
VULNBL_INTEL_STEPPINGS(INTEL_ROCKETLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | ITS),
12581263
VULNBL_INTEL_STEPPINGS(INTEL_ALDERLAKE, X86_STEPPING_ANY, RFDS),
12591264
VULNBL_INTEL_STEPPINGS(INTEL_ALDERLAKE_L, X86_STEPPING_ANY, RFDS),
12601265
VULNBL_INTEL_STEPPINGS(INTEL_RAPTORLAKE, X86_STEPPING_ANY, 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();
@@ -1450,6 +1481,9 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
14501481
if (cpu_has(c, X86_FEATURE_AMD_IBPB) && !cpu_has(c, X86_FEATURE_AMD_IBPB_RET))
14511482
setup_force_cpu_bug(X86_BUG_IBPB_NO_RET);
14521483

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

arch/x86/kvm/x86.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1623,7 +1623,7 @@ EXPORT_SYMBOL_GPL(kvm_emulate_rdpmc);
16231623
ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \
16241624
ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \
16251625
ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO | \
1626-
ARCH_CAP_RFDS_NO | ARCH_CAP_RFDS_CLEAR | ARCH_CAP_BHI_NO)
1626+
ARCH_CAP_RFDS_NO | ARCH_CAP_RFDS_CLEAR | ARCH_CAP_BHI_NO | ARCH_CAP_ITS_NO)
16271627

16281628
static u64 kvm_get_arch_capabilities(void)
16291629
{
@@ -1657,6 +1657,8 @@ static u64 kvm_get_arch_capabilities(void)
16571657
data |= ARCH_CAP_MDS_NO;
16581658
if (!boot_cpu_has_bug(X86_BUG_RFDS))
16591659
data |= ARCH_CAP_RFDS_NO;
1660+
if (!boot_cpu_has_bug(X86_BUG_ITS))
1661+
data |= ARCH_CAP_ITS_NO;
16601662

16611663
if (!boot_cpu_has(X86_FEATURE_RTM)) {
16621664
/*

0 commit comments

Comments
 (0)