Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 48eb8d6a authored by Pawan Gupta's avatar Pawan Gupta Committed by Greg Kroah-Hartman
Browse files

x86/speculation: Disable RRSBA behavior



commit 4ad3278df6fe2b0852b00d5757fc2ccd8e92c26e upstream.

Some Intel processors may use alternate predictors for RETs on
RSB-underflow. This condition may be vulnerable to Branch History
Injection (BHI) and intramode-BTI.

Kernel earlier added spectre_v2 mitigation modes (eIBRS+Retpolines,
eIBRS+LFENCE, Retpolines) which protect indirect CALLs and JMPs against
such attacks. However, on RSB-underflow, RET target prediction may
fallback to alternate predictors. As a result, RET's predicted target
may get influenced by branch history.

A new MSR_IA32_SPEC_CTRL bit (RRSBA_DIS_S) controls this fallback
behavior when in kernel mode. When set, RETs will not take predictions
from alternate predictors, hence mitigating RETs as well. Support for
this is enumerated by CPUID.7.2.EDX[RRSBA_CTRL] (bit2).

For spectre v2 mitigation, when a user selects a mitigation that
protects indirect CALLs and JMPs against BHI and intramode-BTI, set
RRSBA_DIS_S also to protect RETs for RSB-underflow case.

Signed-off-by: default avatarPawan Gupta <pawan.kumar.gupta@linux.intel.com>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
[bwh: Backported to 5.15: adjust context in scattered.c]
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
[sam: Fixed for missing X86_FEATURE_ENTRY_IBPB context]
Signed-off-by: default avatarSamuel Mendoza-Jonas <samjonas@amazon.com>
Signed-off-by: default avatarSuleiman Souhlal <suleiman@google.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 745cd50c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -288,7 +288,7 @@
/* FREE!				(11*32+ 8) */
/* FREE!				(11*32+ 9) */
/* FREE!				(11*32+10) */
/* FREE!				(11*32+11) */
#define X86_FEATURE_RRSBA_CTRL		(11*32+11) /* "" RET prediction control */
#define X86_FEATURE_RETPOLINE		(11*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */
#define X86_FEATURE_RETPOLINE_LFENCE	(11*32+13) /* "" Use LFENCE for Spectre variant 2 */

+9 −0
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@
#define SPEC_CTRL_STIBP			BIT(SPEC_CTRL_STIBP_SHIFT)	/* STIBP mask */
#define SPEC_CTRL_SSBD_SHIFT		2	   /* Speculative Store Bypass Disable bit */
#define SPEC_CTRL_SSBD			BIT(SPEC_CTRL_SSBD_SHIFT)	/* Speculative Store Bypass Disable */
#define SPEC_CTRL_RRSBA_DIS_S_SHIFT	6	   /* Disable RRSBA behavior */
#define SPEC_CTRL_RRSBA_DIS_S		BIT(SPEC_CTRL_RRSBA_DIS_S_SHIFT)

#define MSR_IA32_PRED_CMD		0x00000049 /* Prediction Command */
#define PRED_CMD_IBPB			BIT(0)	   /* Indirect Branch Prediction Barrier */
@@ -121,6 +123,13 @@
						 * bit available to control VERW
						 * behavior.
						 */
#define ARCH_CAP_RRSBA			BIT(19)	/*
						 * Indicates RET may use predictors
						 * other than the RSB. With eIBRS
						 * enabled predictions in kernel mode
						 * are restricted to targets in
						 * kernel.
						 */

#define MSR_IA32_FLUSH_CMD		0x0000010b
#define L1D_FLUSH			BIT(0)	/*
+26 −0
Original line number Diff line number Diff line
@@ -1181,6 +1181,22 @@ static enum spectre_v2_mitigation __init spectre_v2_select_retpoline(void)
	return SPECTRE_V2_RETPOLINE;
}

/* Disable in-kernel use of non-RSB RET predictors */
static void __init spec_ctrl_disable_kernel_rrsba(void)
{
	u64 ia32_cap;

	if (!boot_cpu_has(X86_FEATURE_RRSBA_CTRL))
		return;

	ia32_cap = x86_read_arch_cap_msr();

	if (ia32_cap & ARCH_CAP_RRSBA) {
		x86_spec_ctrl_base |= SPEC_CTRL_RRSBA_DIS_S;
		write_spec_ctrl_current(x86_spec_ctrl_base, true);
	}
}

static void __init spectre_v2_select_mitigation(void)
{
	enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline();
@@ -1274,6 +1290,16 @@ static void __init spectre_v2_select_mitigation(void)
		break;
	}

	/*
	 * Disable alternate RSB predictions in kernel when indirect CALLs and
	 * JMPs gets protection against BHI and Intramode-BTI, but RET
	 * prediction from a non-RSB predictor is still a risk.
	 */
	if (mode == SPECTRE_V2_EIBRS_LFENCE ||
	    mode == SPECTRE_V2_EIBRS_RETPOLINE ||
	    mode == SPECTRE_V2_RETPOLINE)
		spec_ctrl_disable_kernel_rrsba();

	spectre_v2_enabled = mode;
	pr_info("%s\n", spectre_v2_strings[mode]);

+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ struct cpuid_bit {
static const struct cpuid_bit cpuid_bits[] = {
	{ X86_FEATURE_APERFMPERF,       CPUID_ECX,  0, 0x00000006, 0 },
	{ X86_FEATURE_EPB,		CPUID_ECX,  3, 0x00000006, 0 },
	{ X86_FEATURE_RRSBA_CTRL,	CPUID_EDX,  2, 0x00000007, 2 },
	{ X86_FEATURE_CQM_LLC,		CPUID_EDX,  1, 0x0000000f, 0 },
	{ X86_FEATURE_CQM_OCCUP_LLC,	CPUID_EDX,  0, 0x0000000f, 1 },
	{ X86_FEATURE_CQM_MBM_TOTAL,	CPUID_EDX,  1, 0x0000000f, 1 },