arch/x86/kernel/cpu/bugs.c

Source file repositories/reference/linux-study-clean/arch/x86/kernel/cpu/bugs.c

File Facts

System
Linux kernel
Corpus path
arch/x86/kernel/cpu/bugs.c
Extension
.c
Size
107719 bytes
Lines
3738
Domain
Architecture Layer
Bucket
arch/x86
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

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

Annotation

Implementation Notes