]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
x86/its: Enumerate Indirect Target Selection (ITS) bug
authorPawan Gupta <pawan.kumar.gupta@linux.intel.com>
Sat, 22 Jun 2024 00:40:41 +0000 (17:40 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 18 May 2025 06:24:11 +0000 (08:24 +0200)
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 <pawan.kumar.gupta@linux.intel.com>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Josh Poimboeuf <jpoimboe@kernel.org>
Reviewed-by: Alexandre Chartre <alexandre.chartre@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/include/asm/cpufeatures.h
arch/x86/include/asm/msr-index.h
arch/x86/kernel/cpu/common.c
arch/x86/kvm/x86.c

index 55d18eef6775a6f1a3d5ef1ebdf015d9ba39330f..0fde2feb16c62f65dabb3d1c6945aedaf096c204 100644 (file)
 #define X86_BUG_RFDS                   X86_BUG(1*32 + 2) /* CPU is vulnerable to Register File Data Sampling */
 #define X86_BUG_BHI                    X86_BUG(1*32 + 3) /* CPU is affected by Branch History Injection */
 #define X86_BUG_IBPB_NO_RET            X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB omits return target predictions */
+#define X86_BUG_ITS                    X86_BUG(1*32 + 5) /* CPU is affected by Indirect Target Selection */
 #endif /* _ASM_X86_CPUFEATURES_H */
index 623bb48774d44c961314cb5ad48bebc2379a7514..9fbad4cb971bff8f02f2c650119b5716f598381e 100644 (file)
                                                 * VERW clears CPU Register
                                                 * File.
                                                 */
+#define ARCH_CAP_ITS_NO                        BIT_ULL(62) /*
+                                                    * Not susceptible to
+                                                    * Indirect Target Selection.
+                                                    * This bit is not set by
+                                                    * HW, but is synthesized by
+                                                    * VMMs for guests to know
+                                                    * their affected status.
+                                                    */
 
 #define ARCH_CAP_XAPIC_DISABLE         BIT(21) /*
                                                 * IA32_XAPIC_DISABLE_STATUS MSR
index 5bc7943aa5154a06d70543fa6cfee4bbe8f2de0b..1b1df06f6c23e9f3408374f4af995ef6c5c3cbac 100644 (file)
@@ -1272,6 +1272,8 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
 #define GDS            BIT(6)
 /* CPU is affected by Register File Data Sampling */
 #define RFDS           BIT(7)
+/* CPU is affected by Indirect Target Selection */
+#define ITS            BIT(8)
 
 static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
        VULNBL_INTEL_STEPPINGS(IVYBRIDGE,       X86_STEPPING_ANY,               SRBDS),
@@ -1283,22 +1285,25 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
        VULNBL_INTEL_STEPPINGS(BROADWELL_G,     X86_STEPPING_ANY,               SRBDS),
        VULNBL_INTEL_STEPPINGS(BROADWELL_X,     X86_STEPPING_ANY,               MMIO),
        VULNBL_INTEL_STEPPINGS(BROADWELL,       X86_STEPPING_ANY,               SRBDS),
-       VULNBL_INTEL_STEPPINGS(SKYLAKE_X,       X86_STEPPING_ANY,               MMIO | RETBLEED | GDS),
+       VULNBL_INTEL_STEPPINGS(SKYLAKE_X,       X86_STEPPINGS(0x0, 0x5),        MMIO | RETBLEED | GDS),
+       VULNBL_INTEL_STEPPINGS(SKYLAKE_X,       X86_STEPPING_ANY,               MMIO | RETBLEED | GDS | ITS),
        VULNBL_INTEL_STEPPINGS(SKYLAKE_L,       X86_STEPPING_ANY,               MMIO | RETBLEED | GDS | SRBDS),
        VULNBL_INTEL_STEPPINGS(SKYLAKE,         X86_STEPPING_ANY,               MMIO | RETBLEED | GDS | SRBDS),
-       VULNBL_INTEL_STEPPINGS(KABYLAKE_L,      X86_STEPPING_ANY,               MMIO | RETBLEED | GDS | SRBDS),
-       VULNBL_INTEL_STEPPINGS(KABYLAKE,        X86_STEPPING_ANY,               MMIO | RETBLEED | GDS | SRBDS),
+       VULNBL_INTEL_STEPPINGS(KABYLAKE_L,      X86_STEPPINGS(0x0, 0xb),        MMIO | RETBLEED | GDS | SRBDS),
+       VULNBL_INTEL_STEPPINGS(KABYLAKE_L,      X86_STEPPING_ANY,               MMIO | RETBLEED | GDS | SRBDS | ITS),
+       VULNBL_INTEL_STEPPINGS(KABYLAKE,        X86_STEPPINGS(0x0, 0xc),        MMIO | RETBLEED | GDS | SRBDS),
+       VULNBL_INTEL_STEPPINGS(KABYLAKE,        X86_STEPPING_ANY,               MMIO | RETBLEED | GDS | SRBDS | ITS),
        VULNBL_INTEL_STEPPINGS(CANNONLAKE_L,    X86_STEPPING_ANY,               RETBLEED),
-       VULNBL_INTEL_STEPPINGS(ICELAKE_L,       X86_STEPPING_ANY,               MMIO | MMIO_SBDS | RETBLEED | GDS),
-       VULNBL_INTEL_STEPPINGS(ICELAKE_D,       X86_STEPPING_ANY,               MMIO | GDS),
-       VULNBL_INTEL_STEPPINGS(ICELAKE_X,       X86_STEPPING_ANY,               MMIO | GDS),
-       VULNBL_INTEL_STEPPINGS(COMETLAKE,       X86_STEPPING_ANY,               MMIO | MMIO_SBDS | RETBLEED | GDS),
-       VULNBL_INTEL_STEPPINGS(COMETLAKE_L,     X86_STEPPINGS(0x0, 0x0),        MMIO | RETBLEED),
-       VULNBL_INTEL_STEPPINGS(COMETLAKE_L,     X86_STEPPING_ANY,               MMIO | MMIO_SBDS | RETBLEED | GDS),
-       VULNBL_INTEL_STEPPINGS(TIGERLAKE_L,     X86_STEPPING_ANY,               GDS),
-       VULNBL_INTEL_STEPPINGS(TIGERLAKE,       X86_STEPPING_ANY,               GDS),
+       VULNBL_INTEL_STEPPINGS(ICELAKE_L,       X86_STEPPING_ANY,               MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
+       VULNBL_INTEL_STEPPINGS(ICELAKE_D,       X86_STEPPING_ANY,               MMIO | GDS | ITS),
+       VULNBL_INTEL_STEPPINGS(ICELAKE_X,       X86_STEPPING_ANY,               MMIO | GDS | ITS),
+       VULNBL_INTEL_STEPPINGS(COMETLAKE,       X86_STEPPING_ANY,               MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
+       VULNBL_INTEL_STEPPINGS(COMETLAKE_L,     X86_STEPPINGS(0x0, 0x0),        MMIO | RETBLEED | ITS),
+       VULNBL_INTEL_STEPPINGS(COMETLAKE_L,     X86_STEPPING_ANY,               MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
+       VULNBL_INTEL_STEPPINGS(TIGERLAKE_L,     X86_STEPPING_ANY,               GDS | ITS),
+       VULNBL_INTEL_STEPPINGS(TIGERLAKE,       X86_STEPPING_ANY,               GDS | ITS),
        VULNBL_INTEL_STEPPINGS(LAKEFIELD,       X86_STEPPING_ANY,               MMIO | MMIO_SBDS | RETBLEED),
-       VULNBL_INTEL_STEPPINGS(ROCKETLAKE,      X86_STEPPING_ANY,               MMIO | RETBLEED | GDS),
+       VULNBL_INTEL_STEPPINGS(ROCKETLAKE,      X86_STEPPING_ANY,               MMIO | RETBLEED | GDS | ITS),
        VULNBL_INTEL_STEPPINGS(ALDERLAKE,       X86_STEPPING_ANY,               RFDS),
        VULNBL_INTEL_STEPPINGS(ALDERLAKE_L,     X86_STEPPING_ANY,               RFDS),
        VULNBL_INTEL_STEPPINGS(RAPTORLAKE,      X86_STEPPING_ANY,               RFDS),
@@ -1362,6 +1367,32 @@ static bool __init vulnerable_to_rfds(u64 x86_arch_cap_msr)
        return cpu_matches(cpu_vuln_blacklist, RFDS);
 }
 
+static bool __init vulnerable_to_its(u64 x86_arch_cap_msr)
+{
+       /* The "immunity" bit trumps everything else: */
+       if (x86_arch_cap_msr & ARCH_CAP_ITS_NO)
+               return false;
+       if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+               return false;
+
+       /* None of the affected CPUs have BHI_CTRL */
+       if (boot_cpu_has(X86_FEATURE_BHI_CTRL))
+               return false;
+
+       /*
+        * If a VMM did not expose ITS_NO, assume that a guest could
+        * be running on a vulnerable hardware or may migrate to such
+        * hardware.
+        */
+       if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
+               return true;
+
+       if (cpu_matches(cpu_vuln_blacklist, ITS))
+               return true;
+
+       return false;
+}
+
 static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
 {
        u64 x86_arch_cap_msr = x86_read_arch_cap_msr();
@@ -1489,6 +1520,9 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
        if (cpu_has(c, X86_FEATURE_AMD_IBPB) && !cpu_has(c, X86_FEATURE_AMD_IBPB_RET))
                setup_force_cpu_bug(X86_BUG_IBPB_NO_RET);
 
+       if (vulnerable_to_its(x86_arch_cap_msr))
+               setup_force_cpu_bug(X86_BUG_ITS);
+
        if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
                return;
 
index 1eeb01afa40ba97e2abb768bb274f9a976952814..55185670e0e566433f37ecc8926b07ceaf024fef 100644 (file)
@@ -1621,7 +1621,7 @@ static bool kvm_is_immutable_feature_msr(u32 msr)
         ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \
         ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \
         ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO | \
-        ARCH_CAP_RFDS_NO | ARCH_CAP_RFDS_CLEAR | ARCH_CAP_BHI_NO)
+        ARCH_CAP_RFDS_NO | ARCH_CAP_RFDS_CLEAR | ARCH_CAP_BHI_NO | ARCH_CAP_ITS_NO)
 
 static u64 kvm_get_arch_capabilities(void)
 {
@@ -1655,6 +1655,8 @@ static u64 kvm_get_arch_capabilities(void)
                data |= ARCH_CAP_MDS_NO;
        if (!boot_cpu_has_bug(X86_BUG_RFDS))
                data |= ARCH_CAP_RFDS_NO;
+       if (!boot_cpu_has_bug(X86_BUG_ITS))
+               data |= ARCH_CAP_ITS_NO;
 
        if (!boot_cpu_has(X86_FEATURE_RTM)) {
                /*