mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	x86/speculation: Disable RRSBA behavior
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: Pawan Gupta <pawan.kumar.gupta@linux.intel.com> Signed-off-by: Borislav Petkov <bp@suse.de>
This commit is contained in:
		
							parent
							
								
									697977d841
								
							
						
					
					
						commit
						4ad3278df6
					
				
					 5 changed files with 46 additions and 1 deletions
				
			
		| 
						 | 
					@ -297,7 +297,7 @@
 | 
				
			||||||
#define X86_FEATURE_SGX1		(11*32+ 8) /* "" Basic SGX */
 | 
					#define X86_FEATURE_SGX1		(11*32+ 8) /* "" Basic SGX */
 | 
				
			||||||
#define X86_FEATURE_SGX2		(11*32+ 9) /* "" SGX Enclave Dynamic Memory Management (EDMM) */
 | 
					#define X86_FEATURE_SGX2		(11*32+ 9) /* "" SGX Enclave Dynamic Memory Management (EDMM) */
 | 
				
			||||||
#define X86_FEATURE_ENTRY_IBPB		(11*32+10) /* "" Issue an IBPB on kernel entry */
 | 
					#define X86_FEATURE_ENTRY_IBPB		(11*32+10) /* "" Issue an IBPB on kernel entry */
 | 
				
			||||||
/* 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		(11*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */
 | 
				
			||||||
#define X86_FEATURE_RETPOLINE_LFENCE	(11*32+13) /* "" Use LFENCE for Spectre variant 2 */
 | 
					#define X86_FEATURE_RETPOLINE_LFENCE	(11*32+13) /* "" Use LFENCE for Spectre variant 2 */
 | 
				
			||||||
#define X86_FEATURE_RETHUNK		(11*32+14) /* "" Use REturn THUNK */
 | 
					#define X86_FEATURE_RETHUNK		(11*32+14) /* "" Use REturn THUNK */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,6 +51,8 @@
 | 
				
			||||||
#define SPEC_CTRL_STIBP			BIT(SPEC_CTRL_STIBP_SHIFT)	/* STIBP mask */
 | 
					#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_SHIFT		2	   /* Speculative Store Bypass Disable bit */
 | 
				
			||||||
#define SPEC_CTRL_SSBD			BIT(SPEC_CTRL_SSBD_SHIFT)	/* Speculative Store Bypass Disable */
 | 
					#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 MSR_IA32_PRED_CMD		0x00000049 /* Prediction Command */
 | 
				
			||||||
#define PRED_CMD_IBPB			BIT(0)	   /* Indirect Branch Prediction Barrier */
 | 
					#define PRED_CMD_IBPB			BIT(0)	   /* Indirect Branch Prediction Barrier */
 | 
				
			||||||
| 
						 | 
					@ -141,6 +143,13 @@
 | 
				
			||||||
						 * bit available to control VERW
 | 
											 * bit available to control VERW
 | 
				
			||||||
						 * behavior.
 | 
											 * 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 MSR_IA32_FLUSH_CMD		0x0000010b
 | 
				
			||||||
#define L1D_FLUSH			BIT(0)	/*
 | 
					#define L1D_FLUSH			BIT(0)	/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1318,6 +1318,22 @@ static enum spectre_v2_mitigation __init spectre_v2_select_retpoline(void)
 | 
				
			||||||
	return SPECTRE_V2_RETPOLINE;
 | 
						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)
 | 
					static void __init spectre_v2_select_mitigation(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline();
 | 
						enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline();
 | 
				
			||||||
| 
						 | 
					@ -1412,6 +1428,16 @@ static void __init spectre_v2_select_mitigation(void)
 | 
				
			||||||
		break;
 | 
							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;
 | 
						spectre_v2_enabled = mode;
 | 
				
			||||||
	pr_info("%s\n", spectre_v2_strings[mode]);
 | 
						pr_info("%s\n", spectre_v2_strings[mode]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,6 +27,7 @@ static const struct cpuid_bit cpuid_bits[] = {
 | 
				
			||||||
	{ X86_FEATURE_APERFMPERF,       CPUID_ECX,  0, 0x00000006, 0 },
 | 
						{ X86_FEATURE_APERFMPERF,       CPUID_ECX,  0, 0x00000006, 0 },
 | 
				
			||||||
	{ X86_FEATURE_EPB,		CPUID_ECX,  3, 0x00000006, 0 },
 | 
						{ X86_FEATURE_EPB,		CPUID_ECX,  3, 0x00000006, 0 },
 | 
				
			||||||
	{ X86_FEATURE_INTEL_PPIN,	CPUID_EBX,  0, 0x00000007, 1 },
 | 
						{ X86_FEATURE_INTEL_PPIN,	CPUID_EBX,  0, 0x00000007, 1 },
 | 
				
			||||||
 | 
						{ X86_FEATURE_RRSBA_CTRL,	CPUID_EDX,  2, 0x00000007, 2 },
 | 
				
			||||||
	{ X86_FEATURE_CQM_LLC,		CPUID_EDX,  1, 0x0000000f, 0 },
 | 
						{ X86_FEATURE_CQM_LLC,		CPUID_EDX,  1, 0x0000000f, 0 },
 | 
				
			||||||
	{ X86_FEATURE_CQM_OCCUP_LLC,	CPUID_EDX,  0, 0x0000000f, 1 },
 | 
						{ X86_FEATURE_CQM_OCCUP_LLC,	CPUID_EDX,  0, 0x0000000f, 1 },
 | 
				
			||||||
	{ X86_FEATURE_CQM_MBM_TOTAL,	CPUID_EDX,  1, 0x0000000f, 1 },
 | 
						{ X86_FEATURE_CQM_MBM_TOTAL,	CPUID_EDX,  1, 0x0000000f, 1 },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,6 +51,8 @@
 | 
				
			||||||
#define SPEC_CTRL_STIBP			BIT(SPEC_CTRL_STIBP_SHIFT)	/* STIBP mask */
 | 
					#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_SHIFT		2	   /* Speculative Store Bypass Disable bit */
 | 
				
			||||||
#define SPEC_CTRL_SSBD			BIT(SPEC_CTRL_SSBD_SHIFT)	/* Speculative Store Bypass Disable */
 | 
					#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 MSR_IA32_PRED_CMD		0x00000049 /* Prediction Command */
 | 
				
			||||||
#define PRED_CMD_IBPB			BIT(0)	   /* Indirect Branch Prediction Barrier */
 | 
					#define PRED_CMD_IBPB			BIT(0)	   /* Indirect Branch Prediction Barrier */
 | 
				
			||||||
| 
						 | 
					@ -140,6 +142,13 @@
 | 
				
			||||||
						 * bit available to control VERW
 | 
											 * bit available to control VERW
 | 
				
			||||||
						 * behavior.
 | 
											 * 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 MSR_IA32_FLUSH_CMD		0x0000010b
 | 
				
			||||||
#define L1D_FLUSH			BIT(0)	/*
 | 
					#define L1D_FLUSH			BIT(0)	/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue