]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
x86/its: Add "vmexit" option to skip mitigation on some CPUs
authorPawan Gupta <pawan.kumar.gupta@linux.intel.com>
Mon, 18 Nov 2024 17:53:12 +0000 (09:53 -0800)
committerDave Hansen <dave.hansen@linux.intel.com>
Fri, 9 May 2025 20:22:05 +0000 (13:22 -0700)
Ice Lake generation CPUs are not affected by guest/host isolation part of
ITS. If a user is only concerned about KVM guests, they can now choose a
new cmdline option "vmexit" that will not deploy the ITS mitigation when
CPU is not affected by guest/host isolation. This saves the performance
overhead of ITS mitigation on Ice Lake gen CPUs.

When "vmexit" option selected, if the CPU is affected by ITS guest/host
isolation, the default ITS mitigation is deployed.

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>
Documentation/admin-guide/kernel-parameters.txt
arch/x86/include/asm/cpufeatures.h
arch/x86/kernel/cpu/bugs.c
arch/x86/kernel/cpu/common.c

index d3e78e795e0d6fdd2ad286014b8b04480ea1ccba..e70d15095f28b479624e63e49a8392475aae7ff7 100644 (file)
                        off:    Disable mitigation.
                        force:  Force the ITS bug and deploy default
                                mitigation.
+                       vmexit: Only deploy mitigation if CPU is affected by
+                               guest/host isolation part of ITS.
 
                        For details see:
                        Documentation/admin-guide/hw-vuln/indirect-target-selection.rst
index 03af8191073a21a9acfd0c5914c32fcccbf0558f..39e61212ac9a916dbb2ceb1b0b95e8d71303c547 100644 (file)
 #define X86_BUG_IBPB_NO_RET            X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB omits return target predictions */
 #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 */
 #define X86_BUG_ITS                    X86_BUG(1*32 + 6) /* "its" CPU is affected by Indirect Target Selection */
+#define X86_BUG_ITS_NATIVE_ONLY                X86_BUG(1*32 + 7) /* "its_native_only" CPU is affected by ITS, VMX is not affected */
 #endif /* _ASM_X86_CPUFEATURES_H */
index 417596ce5352b520f8190cda8633d09c6ff6ffc3..e919d645d83031c4f88c5b6483786eda13500663 100644 (file)
@@ -1203,16 +1203,19 @@ do_cmd_auto:
 enum its_mitigation_cmd {
        ITS_CMD_OFF,
        ITS_CMD_ON,
+       ITS_CMD_VMEXIT,
 };
 
 enum its_mitigation {
        ITS_MITIGATION_OFF,
+       ITS_MITIGATION_VMEXIT_ONLY,
        ITS_MITIGATION_ALIGNED_THUNKS,
        ITS_MITIGATION_RETPOLINE_STUFF,
 };
 
 static const char * const its_strings[] = {
        [ITS_MITIGATION_OFF]                    = "Vulnerable",
+       [ITS_MITIGATION_VMEXIT_ONLY]            = "Mitigation: Vulnerable, KVM: Not affected",
        [ITS_MITIGATION_ALIGNED_THUNKS]         = "Mitigation: Aligned branch/return thunks",
        [ITS_MITIGATION_RETPOLINE_STUFF]        = "Mitigation: Retpolines, Stuffing RSB",
 };
@@ -1239,6 +1242,8 @@ static int __init its_parse_cmdline(char *str)
        } else if (!strcmp(str, "force")) {
                its_cmd = ITS_CMD_ON;
                setup_force_cpu_bug(X86_BUG_ITS);
+       } else if (!strcmp(str, "vmexit")) {
+               its_cmd = ITS_CMD_VMEXIT;
        } else {
                pr_err("Ignoring unknown indirect_target_selection option (%s).", str);
        }
@@ -1294,6 +1299,12 @@ static void __init its_select_mitigation(void)
        case ITS_CMD_OFF:
                its_mitigation = ITS_MITIGATION_OFF;
                break;
+       case ITS_CMD_VMEXIT:
+               if (boot_cpu_has_bug(X86_BUG_ITS_NATIVE_ONLY)) {
+                       its_mitigation = ITS_MITIGATION_VMEXIT_ONLY;
+                       goto out;
+               }
+               fallthrough;
        case ITS_CMD_ON:
                its_mitigation = ITS_MITIGATION_ALIGNED_THUNKS;
                if (!boot_cpu_has(X86_FEATURE_RETPOLINE))
index accdee7ab1f70f271293a534eb3f594b53abef4d..6a6c3be5af6a86f3b4d0d85cb30c5a100b486560 100644 (file)
@@ -1229,6 +1229,8 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
 #define RFDS           BIT(7)
 /* CPU is affected by Indirect Target Selection */
 #define ITS            BIT(8)
+/* CPU is affected by Indirect Target Selection, but guest-host isolation is not affected */
+#define ITS_NATIVE_ONLY        BIT(9)
 
 static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
        VULNBL_INTEL_STEPS(INTEL_IVYBRIDGE,          X86_STEP_MAX,      SRBDS),
@@ -1249,16 +1251,16 @@ static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
        VULNBL_INTEL_STEPS(INTEL_KABYLAKE,                    0xc,      MMIO | RETBLEED | GDS | SRBDS),
        VULNBL_INTEL_STEPS(INTEL_KABYLAKE,           X86_STEP_MAX,      MMIO | RETBLEED | GDS | SRBDS | ITS),
        VULNBL_INTEL_STEPS(INTEL_CANNONLAKE_L,       X86_STEP_MAX,      RETBLEED),
-       VULNBL_INTEL_STEPS(INTEL_ICELAKE_L,          X86_STEP_MAX,      MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
-       VULNBL_INTEL_STEPS(INTEL_ICELAKE_D,          X86_STEP_MAX,      MMIO | GDS | ITS),
-       VULNBL_INTEL_STEPS(INTEL_ICELAKE_X,          X86_STEP_MAX,      MMIO | GDS | ITS),
+       VULNBL_INTEL_STEPS(INTEL_ICELAKE_L,          X86_STEP_MAX,      MMIO | MMIO_SBDS | RETBLEED | GDS | ITS | ITS_NATIVE_ONLY),
+       VULNBL_INTEL_STEPS(INTEL_ICELAKE_D,          X86_STEP_MAX,      MMIO | GDS | ITS | ITS_NATIVE_ONLY),
+       VULNBL_INTEL_STEPS(INTEL_ICELAKE_X,          X86_STEP_MAX,      MMIO | GDS | ITS | ITS_NATIVE_ONLY),
        VULNBL_INTEL_STEPS(INTEL_COMETLAKE,          X86_STEP_MAX,      MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
        VULNBL_INTEL_STEPS(INTEL_COMETLAKE_L,                 0x0,      MMIO | RETBLEED | ITS),
        VULNBL_INTEL_STEPS(INTEL_COMETLAKE_L,        X86_STEP_MAX,      MMIO | MMIO_SBDS | RETBLEED | GDS | ITS),
-       VULNBL_INTEL_STEPS(INTEL_TIGERLAKE_L,        X86_STEP_MAX,      GDS | ITS),
-       VULNBL_INTEL_STEPS(INTEL_TIGERLAKE,          X86_STEP_MAX,      GDS | ITS),
+       VULNBL_INTEL_STEPS(INTEL_TIGERLAKE_L,        X86_STEP_MAX,      GDS | ITS | ITS_NATIVE_ONLY),
+       VULNBL_INTEL_STEPS(INTEL_TIGERLAKE,          X86_STEP_MAX,      GDS | ITS | ITS_NATIVE_ONLY),
        VULNBL_INTEL_STEPS(INTEL_LAKEFIELD,          X86_STEP_MAX,      MMIO | MMIO_SBDS | RETBLEED),
-       VULNBL_INTEL_STEPS(INTEL_ROCKETLAKE,         X86_STEP_MAX,      MMIO | RETBLEED | GDS | ITS),
+       VULNBL_INTEL_STEPS(INTEL_ROCKETLAKE,         X86_STEP_MAX,      MMIO | RETBLEED | GDS | ITS | ITS_NATIVE_ONLY),
        VULNBL_INTEL_TYPE(INTEL_ALDERLAKE,                   ATOM,      RFDS),
        VULNBL_INTEL_STEPS(INTEL_ALDERLAKE_L,        X86_STEP_MAX,      RFDS),
        VULNBL_INTEL_TYPE(INTEL_RAPTORLAKE,                  ATOM,      RFDS),
@@ -1480,8 +1482,11 @@ 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))
+       if (vulnerable_to_its(x86_arch_cap_msr)) {
                setup_force_cpu_bug(X86_BUG_ITS);
+               if (cpu_matches(cpu_vuln_blacklist, ITS_NATIVE_ONLY))
+                       setup_force_cpu_bug(X86_BUG_ITS_NATIVE_ONLY);
+       }
 
        if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
                return;