3816 lines · 107.2 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0/* *  Copyright (C) 1994  Linus Torvalds * *  Cyrix stuff, June 1998 by: *	- Rafael R. Reilova (moved everything from head.S), *        <rreilova@ececs.uc.edu> *	- Channing Corn (tests & fixes), *	- Andrew D. Balsa (code cleanup). */#include <linux/init.h>#include <linux/cpu.h>#include <linux/module.h>#include <linux/nospec.h>#include <linux/prctl.h>#include <linux/sched/smt.h>#include <linux/pgtable.h>#include <linux/bpf.h>#include <linux/filter.h>#include <linux/kvm_types.h> #include <asm/spec-ctrl.h>#include <asm/cmdline.h>#include <asm/bugs.h>#include <asm/processor.h>#include <asm/processor-flags.h>#include <asm/fpu/api.h>#include <asm/msr.h>#include <asm/vmx.h>#include <asm/cpu_device_id.h>#include <asm/e820/api.h>#include <asm/hypervisor.h>#include <asm/tlbflush.h>#include <asm/cpu.h> #include "cpu.h" /* * Speculation Vulnerability Handling * * Each vulnerability is handled with the following functions: *   <vuln>_select_mitigation() -- Selects a mitigation to use.  This should *				   take into account all relevant command line *				   options. *   <vuln>_update_mitigation() -- This is called after all vulnerabilities have *				   selected a mitigation, in case the selection *				   may want to change based on other choices *				   made.  This function is optional. *   <vuln>_apply_mitigation() -- Enable the selected mitigation. * * The compile-time mitigation in all cases should be AUTO.  An explicit * command-line option can override AUTO.  If no such option is * provided, <vuln>_select_mitigation() will override AUTO to the best * mitigation option. */ /* The base value of the SPEC_CTRL MSR without task-specific bits set */u64 x86_spec_ctrl_base; /* The current value of the SPEC_CTRL MSR with task-specific bits set */DEFINE_PER_CPU(u64, x86_spec_ctrl_current);EXPORT_PER_CPU_SYMBOL_GPL(x86_spec_ctrl_current); /* * Set when the CPU has run a potentially malicious guest. An IBPB will * be needed to before running userspace. That IBPB will flush the branch * predictor content. */DEFINE_PER_CPU(bool, x86_ibpb_exit_to_user);EXPORT_PER_CPU_SYMBOL_GPL(x86_ibpb_exit_to_user); u64 x86_pred_cmd __ro_after_init = PRED_CMD_IBPB; static u64 __ro_after_init x86_arch_cap_msr; static DEFINE_MUTEX(spec_ctrl_mutex); void (*x86_return_thunk)(void) __ro_after_init = __x86_return_thunk; static void __init set_return_thunk(void *thunk){	x86_return_thunk = thunk; 	pr_info("active return thunk: %ps\n", thunk);} /* Update SPEC_CTRL MSR and its cached copy unconditionally */static void update_spec_ctrl(u64 val){	this_cpu_write(x86_spec_ctrl_current, val);	wrmsrq(MSR_IA32_SPEC_CTRL, val);} /* * Keep track of the SPEC_CTRL MSR value for the current task, which may differ * from x86_spec_ctrl_base due to STIBP/SSB in __speculation_ctrl_update(). */void update_spec_ctrl_cond(u64 val){	if (this_cpu_read(x86_spec_ctrl_current) == val)		return; 	this_cpu_write(x86_spec_ctrl_current, val); 	/*	 * When KERNEL_IBRS this MSR is written on return-to-user, unless	 * forced the update can be delayed until that time.	 */	if (!cpu_feature_enabled(X86_FEATURE_KERNEL_IBRS))		wrmsrq(MSR_IA32_SPEC_CTRL, val);} noinstr u64 spec_ctrl_current(void){	return this_cpu_read(x86_spec_ctrl_current);}EXPORT_SYMBOL_GPL(spec_ctrl_current); /* * AMD specific MSR info for Speculative Store Bypass control. * x86_amd_ls_cfg_ssbd_mask is initialized in identify_boot_cpu(). */u64 __ro_after_init x86_amd_ls_cfg_base;u64 __ro_after_init x86_amd_ls_cfg_ssbd_mask; /* Control conditional STIBP in switch_to() */DEFINE_STATIC_KEY_FALSE(switch_to_cond_stibp);/* Control conditional IBPB in switch_mm() */DEFINE_STATIC_KEY_FALSE(switch_mm_cond_ibpb);/* Control unconditional IBPB in switch_mm() */DEFINE_STATIC_KEY_FALSE(switch_mm_always_ibpb); /* Control IBPB on vCPU load */DEFINE_STATIC_KEY_FALSE(switch_vcpu_ibpb);EXPORT_SYMBOL_FOR_KVM(switch_vcpu_ibpb); /* Control CPU buffer clear before idling (halt, mwait) */DEFINE_STATIC_KEY_FALSE(cpu_buf_idle_clear);EXPORT_SYMBOL_GPL(cpu_buf_idle_clear); /* * Controls whether l1d flush based mitigations are enabled, * based on hw features and admin setting via boot parameter * defaults to false */DEFINE_STATIC_KEY_FALSE(switch_mm_cond_l1d_flush); #undef pr_fmt#define pr_fmt(fmt)	"mitigations: " fmt static void __init cpu_print_attack_vectors(void){	pr_info("Enabled attack vectors: "); 	if (cpu_attack_vector_mitigated(CPU_MITIGATE_USER_KERNEL))		pr_cont("user_kernel, "); 	if (cpu_attack_vector_mitigated(CPU_MITIGATE_USER_USER))		pr_cont("user_user, "); 	if (cpu_attack_vector_mitigated(CPU_MITIGATE_GUEST_HOST))		pr_cont("guest_host, "); 	if (cpu_attack_vector_mitigated(CPU_MITIGATE_GUEST_GUEST))		pr_cont("guest_guest, "); 	pr_cont("SMT mitigations: "); 	switch (smt_mitigations) {	case SMT_MITIGATIONS_OFF:		pr_cont("off\n");		break;	case SMT_MITIGATIONS_AUTO:		pr_cont("auto\n");		break;	case SMT_MITIGATIONS_ON:		pr_cont("on\n");	}} /* * NOTE: This function is *only* called for SVM, since Intel uses * MSR_IA32_SPEC_CTRL for SSBD. */voidx86_virt_spec_ctrl(u64 guest_virt_spec_ctrl, bool setguest){	u64 guestval, hostval;	struct thread_info *ti = current_thread_info(); 	/*	 * If SSBD is not handled in MSR_SPEC_CTRL on AMD, update	 * MSR_AMD64_L2_CFG or MSR_VIRT_SPEC_CTRL if supported.	 */	if (!cpu_feature_enabled(X86_FEATURE_LS_CFG_SSBD) &&	    !cpu_feature_enabled(X86_FEATURE_VIRT_SSBD))		return; 	/*	 * If the host has SSBD mitigation enabled, force it in the host's	 * virtual MSR value. If its not permanently enabled, evaluate	 * current's TIF_SSBD thread flag.	 */	if (cpu_feature_enabled(X86_FEATURE_SPEC_STORE_BYPASS_DISABLE))		hostval = SPEC_CTRL_SSBD;	else		hostval = ssbd_tif_to_spec_ctrl(ti->flags); 	/* Sanitize the guest value */	guestval = guest_virt_spec_ctrl & SPEC_CTRL_SSBD; 	if (hostval != guestval) {		unsigned long tif; 		tif = setguest ? ssbd_spec_ctrl_to_tif(guestval) :				 ssbd_spec_ctrl_to_tif(hostval); 		speculation_ctrl_update(tif);	}}EXPORT_SYMBOL_FOR_KVM(x86_virt_spec_ctrl); static void x86_amd_ssb_disable(void){	u64 msrval = x86_amd_ls_cfg_base | x86_amd_ls_cfg_ssbd_mask; 	if (boot_cpu_has(X86_FEATURE_VIRT_SSBD))		wrmsrq(MSR_AMD64_VIRT_SPEC_CTRL, SPEC_CTRL_SSBD);	else if (boot_cpu_has(X86_FEATURE_LS_CFG_SSBD))		wrmsrq(MSR_AMD64_LS_CFG, msrval);} #undef pr_fmt#define pr_fmt(fmt)	"MDS: " fmt /* * Returns true if vulnerability should be mitigated based on the * selected attack vector controls. * * See Documentation/admin-guide/hw-vuln/attack_vector_controls.rst */static bool __init should_mitigate_vuln(unsigned int bug){	switch (bug) {	/*	 * The only runtime-selected spectre_v1 mitigations in the kernel are	 * related to SWAPGS protection on kernel entry.  Therefore, protection	 * is only required for the user->kernel attack vector.	 */	case X86_BUG_SPECTRE_V1:		return cpu_attack_vector_mitigated(CPU_MITIGATE_USER_KERNEL); 	case X86_BUG_SPECTRE_V2:	case X86_BUG_RETBLEED:	case X86_BUG_L1TF:	case X86_BUG_ITS:		return cpu_attack_vector_mitigated(CPU_MITIGATE_USER_KERNEL) ||		       cpu_attack_vector_mitigated(CPU_MITIGATE_GUEST_HOST); 	case X86_BUG_SPECTRE_V2_USER:		return cpu_attack_vector_mitigated(CPU_MITIGATE_USER_USER) ||		       cpu_attack_vector_mitigated(CPU_MITIGATE_GUEST_GUEST); 	/*	 * All the vulnerabilities below allow potentially leaking data	 * across address spaces.  Therefore, mitigation is required for	 * any of these 4 attack vectors.	 */	case X86_BUG_MDS:	case X86_BUG_TAA:	case X86_BUG_MMIO_STALE_DATA:	case X86_BUG_RFDS:	case X86_BUG_SRBDS:		return cpu_attack_vector_mitigated(CPU_MITIGATE_USER_KERNEL) ||		       cpu_attack_vector_mitigated(CPU_MITIGATE_GUEST_HOST) ||		       cpu_attack_vector_mitigated(CPU_MITIGATE_USER_USER) ||		       cpu_attack_vector_mitigated(CPU_MITIGATE_GUEST_GUEST); 	case X86_BUG_GDS:		return cpu_attack_vector_mitigated(CPU_MITIGATE_USER_KERNEL) ||		       cpu_attack_vector_mitigated(CPU_MITIGATE_GUEST_HOST) ||		       cpu_attack_vector_mitigated(CPU_MITIGATE_USER_USER) ||		       cpu_attack_vector_mitigated(CPU_MITIGATE_GUEST_GUEST) ||		       (smt_mitigations != SMT_MITIGATIONS_OFF); 	case X86_BUG_SPEC_STORE_BYPASS:		return cpu_attack_vector_mitigated(CPU_MITIGATE_USER_USER); 	case X86_BUG_VMSCAPE:		return cpu_attack_vector_mitigated(CPU_MITIGATE_GUEST_HOST); 	default:		WARN(1, "Unknown bug %x\n", bug);		return false;	}} /* Default mitigation for MDS-affected CPUs */static enum mds_mitigations mds_mitigation __ro_after_init =	IS_ENABLED(CONFIG_MITIGATION_MDS) ? MDS_MITIGATION_AUTO : MDS_MITIGATION_OFF;static bool mds_nosmt __ro_after_init = false; static const char * const mds_strings[] = {	[MDS_MITIGATION_OFF]	= "Vulnerable",	[MDS_MITIGATION_FULL]	= "Mitigation: Clear CPU buffers",	[MDS_MITIGATION_VMWERV]	= "Vulnerable: Clear CPU buffers attempted, no microcode",}; enum taa_mitigations {	TAA_MITIGATION_OFF,	TAA_MITIGATION_AUTO,	TAA_MITIGATION_UCODE_NEEDED,	TAA_MITIGATION_VERW,	TAA_MITIGATION_TSX_DISABLED,}; /* Default mitigation for TAA-affected CPUs */static enum taa_mitigations taa_mitigation __ro_after_init =	IS_ENABLED(CONFIG_MITIGATION_TAA) ? TAA_MITIGATION_AUTO : TAA_MITIGATION_OFF; enum mmio_mitigations {	MMIO_MITIGATION_OFF,	MMIO_MITIGATION_AUTO,	MMIO_MITIGATION_UCODE_NEEDED,	MMIO_MITIGATION_VERW,}; /* Default mitigation for Processor MMIO Stale Data vulnerabilities */static enum mmio_mitigations mmio_mitigation __ro_after_init =	IS_ENABLED(CONFIG_MITIGATION_MMIO_STALE_DATA) ?	MMIO_MITIGATION_AUTO : MMIO_MITIGATION_OFF; enum rfds_mitigations {	RFDS_MITIGATION_OFF,	RFDS_MITIGATION_AUTO,	RFDS_MITIGATION_VERW,	RFDS_MITIGATION_UCODE_NEEDED,}; /* Default mitigation for Register File Data Sampling */static enum rfds_mitigations rfds_mitigation __ro_after_init =	IS_ENABLED(CONFIG_MITIGATION_RFDS) ? RFDS_MITIGATION_AUTO : RFDS_MITIGATION_OFF; /* * Set if any of MDS/TAA/MMIO/RFDS are going to enable VERW clearing on exit to * userspace *and* on entry to KVM guests. */static bool verw_clear_cpu_buf_mitigation_selected __ro_after_init; static void __init mds_select_mitigation(void){	if (!boot_cpu_has_bug(X86_BUG_MDS)) {		mds_mitigation = MDS_MITIGATION_OFF;		return;	} 	if (mds_mitigation == MDS_MITIGATION_AUTO) {		if (should_mitigate_vuln(X86_BUG_MDS))			mds_mitigation = MDS_MITIGATION_FULL;		else			mds_mitigation = MDS_MITIGATION_OFF;	} 	if (mds_mitigation == MDS_MITIGATION_OFF)		return; 	verw_clear_cpu_buf_mitigation_selected = true;} static void __init mds_update_mitigation(void){	if (!boot_cpu_has_bug(X86_BUG_MDS))		return; 	/* If TAA, MMIO, or RFDS are being mitigated, MDS gets mitigated too. */	if (verw_clear_cpu_buf_mitigation_selected)		mds_mitigation = MDS_MITIGATION_FULL; 	if (mds_mitigation == MDS_MITIGATION_FULL) {		if (!boot_cpu_has(X86_FEATURE_MD_CLEAR))			mds_mitigation = MDS_MITIGATION_VMWERV;	} 	pr_info("%s\n", mds_strings[mds_mitigation]);} static void __init mds_apply_mitigation(void){	if (mds_mitigation == MDS_MITIGATION_FULL ||	    mds_mitigation == MDS_MITIGATION_VMWERV) {		setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);		setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF_VM);		if (!boot_cpu_has(X86_BUG_MSBDS_ONLY) &&		    (mds_nosmt || smt_mitigations == SMT_MITIGATIONS_ON))			cpu_smt_disable(false);	}} static int __init mds_cmdline(char *str){	if (!boot_cpu_has_bug(X86_BUG_MDS))		return 0; 	if (!str)		return -EINVAL; 	if (!strcmp(str, "off"))		mds_mitigation = MDS_MITIGATION_OFF;	else if (!strcmp(str, "full"))		mds_mitigation = MDS_MITIGATION_FULL;	else if (!strcmp(str, "full,nosmt")) {		mds_mitigation = MDS_MITIGATION_FULL;		mds_nosmt = true;	} 	return 0;}early_param("mds", mds_cmdline); #undef pr_fmt#define pr_fmt(fmt)	"TAA: " fmt static bool taa_nosmt __ro_after_init; static const char * const taa_strings[] = {	[TAA_MITIGATION_OFF]		= "Vulnerable",	[TAA_MITIGATION_UCODE_NEEDED]	= "Vulnerable: Clear CPU buffers attempted, no microcode",	[TAA_MITIGATION_VERW]		= "Mitigation: Clear CPU buffers",	[TAA_MITIGATION_TSX_DISABLED]	= "Mitigation: TSX disabled",}; static bool __init taa_vulnerable(void){	return boot_cpu_has_bug(X86_BUG_TAA) && boot_cpu_has(X86_FEATURE_RTM);} static void __init taa_select_mitigation(void){	if (!boot_cpu_has_bug(X86_BUG_TAA)) {		taa_mitigation = TAA_MITIGATION_OFF;		return;	} 	/* TSX previously disabled by tsx=off */	if (!boot_cpu_has(X86_FEATURE_RTM)) {		taa_mitigation = TAA_MITIGATION_TSX_DISABLED;		return;	} 	/* Microcode will be checked in taa_update_mitigation(). */	if (taa_mitigation == TAA_MITIGATION_AUTO) {		if (should_mitigate_vuln(X86_BUG_TAA))			taa_mitigation = TAA_MITIGATION_VERW;		else			taa_mitigation = TAA_MITIGATION_OFF;	} 	if (taa_mitigation != TAA_MITIGATION_OFF)		verw_clear_cpu_buf_mitigation_selected = true;} static void __init taa_update_mitigation(void){	if (!taa_vulnerable())		return; 	if (verw_clear_cpu_buf_mitigation_selected)		taa_mitigation = TAA_MITIGATION_VERW; 	if (taa_mitigation == TAA_MITIGATION_VERW) {		/* Check if the requisite ucode is available. */		if (!boot_cpu_has(X86_FEATURE_MD_CLEAR))			taa_mitigation = TAA_MITIGATION_UCODE_NEEDED; 		/*		 * VERW doesn't clear the CPU buffers when MD_CLEAR=1 and MDS_NO=1.		 * A microcode update fixes this behavior to clear CPU buffers. It also		 * adds support for MSR_IA32_TSX_CTRL which is enumerated by the		 * ARCH_CAP_TSX_CTRL_MSR bit.		 *		 * On MDS_NO=1 CPUs if ARCH_CAP_TSX_CTRL_MSR is not set, microcode		 * update is required.		 */		if ((x86_arch_cap_msr & ARCH_CAP_MDS_NO) &&		   !(x86_arch_cap_msr & ARCH_CAP_TSX_CTRL_MSR))			taa_mitigation = TAA_MITIGATION_UCODE_NEEDED;	} 	pr_info("%s\n", taa_strings[taa_mitigation]);} static void __init taa_apply_mitigation(void){	if (taa_mitigation == TAA_MITIGATION_VERW ||	    taa_mitigation == TAA_MITIGATION_UCODE_NEEDED) {		/*		 * TSX is enabled, select alternate mitigation for TAA which is		 * the same as MDS. Enable MDS static branch to clear CPU buffers.		 *		 * For guests that can't determine whether the correct microcode is		 * present on host, enable the mitigation for UCODE_NEEDED as well.

Lines 1–500 of 3816.