Commit 5a15d834 authored by Borislav Petkov (AMD)'s avatar Borislav Petkov (AMD)
Browse files

x86/srso: Tie SBPB bit setting to microcode patch detection



The SBPB bit in MSR_IA32_PRED_CMD is supported only after a microcode
patch has been applied so set X86_FEATURE_SBPB only then. Otherwise,
guests would attempt to set that bit and #GP on the MSR write.

While at it, make SMT detection more robust as some guests - depending
on how and what CPUID leafs their report - lead to cpu_smt_control
getting set to CPU_SMT_NOT_SUPPORTED but SRSO_NO should be set for any
guest incarnation where one simply cannot do SMT, for whatever reason.

Fixes: fb3bd914 ("x86/srso: Add a Speculative RAS Overflow mitigation")
Reported-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reported-by: default avatarSalvatore Bonaccorso <carnil@debian.org>
Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
parent 3bbbe97a
Loading
Loading
Loading
Loading
+12 −7
Original line number Diff line number Diff line
@@ -1238,14 +1238,19 @@ EXPORT_SYMBOL_GPL(amd_get_highest_perf);

bool cpu_has_ibpb_brtype_microcode(void)
{
	u8 fam = boot_cpu_data.x86;

	switch (boot_cpu_data.x86) {
	/* Zen1/2 IBPB flushes branch type predictions too. */
	if (fam == 0x17)
	case 0x17:
		return boot_cpu_has(X86_FEATURE_AMD_IBPB);
	case 0x19:
		/* Poke the MSR bit on Zen3/4 to check its presence. */
	else if (fam == 0x19)
		return !wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB);
	else
		if (!wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB)) {
			setup_force_cpu_cap(X86_FEATURE_SBPB);
			return true;
		} else {
			return false;
		}
	default:
		return false;
	}
}
+3 −4
Original line number Diff line number Diff line
@@ -2265,14 +2265,13 @@ static void __init srso_select_mitigation(void)
		 * flags for guests.
		 */
		setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE);
		setup_force_cpu_cap(X86_FEATURE_SBPB);

		/*
		 * Zen1/2 with SMT off aren't vulnerable after the right
		 * IBPB microcode has been applied.
		 */
		if ((boot_cpu_data.x86 < 0x19) &&
		    (cpu_smt_control == CPU_SMT_DISABLED))
		    (!cpu_smt_possible() || (cpu_smt_control == CPU_SMT_DISABLED)))
			setup_force_cpu_cap(X86_FEATURE_SRSO_NO);
	}

@@ -2345,8 +2344,8 @@ static void __init srso_select_mitigation(void)
	pr_info("%s%s\n", srso_strings[srso_mitigation], (has_microcode ? "" : ", no microcode"));

pred_cmd:
	if (boot_cpu_has(X86_FEATURE_SRSO_NO) ||
	    srso_cmd == SRSO_CMD_OFF)
	if ((boot_cpu_has(X86_FEATURE_SRSO_NO) || srso_cmd == SRSO_CMD_OFF) &&
	     boot_cpu_has(X86_FEATURE_SBPB))
		x86_pred_cmd = PRED_CMD_SBPB;
}