Commit 2665281a authored by Pawan Gupta's avatar Pawan Gupta Committed by Dave Hansen
Browse files

x86/its: Add "vmexit" option to skip mitigation on some CPUs



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: default avatarPawan Gupta <pawan.kumar.gupta@linux.intel.com>
Signed-off-by: default avatarDave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: default avatarJosh Poimboeuf <jpoimboe@kernel.org>
Reviewed-by: default avatarAlexandre Chartre <alexandre.chartre@oracle.com>
parent f4818881
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -2210,6 +2210,8 @@
			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
+1 −0
Original line number Diff line number Diff line
@@ -535,4 +535,5 @@
#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 */
+11 −0
Original line number Diff line number Diff line
@@ -1203,16 +1203,19 @@ static void __init retbleed_select_mitigation(void)
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))
+12 −7
Original line number Diff line number Diff line
@@ -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;