| From 5a15d8348881e9371afdf9f5357a135489496955 Mon Sep 17 00:00:00 2001 |
| From: "Borislav Petkov (AMD)" <bp@alien8.de> |
| Date: Mon, 7 Aug 2023 10:46:04 +0200 |
| Subject: x86/srso: Tie SBPB bit setting to microcode patch detection |
| |
| From: Borislav Petkov (AMD) <bp@alien8.de> |
| |
| commit 5a15d8348881e9371afdf9f5357a135489496955 upstream. |
| |
| 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: fb3bd914b3ec ("x86/srso: Add a Speculative RAS Overflow mitigation") |
| Reported-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> |
| Reported-by: Salvatore Bonaccorso <carnil@debian.org> |
| Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/x86/kernel/cpu/amd.c | 19 ++++++++++++------- |
| arch/x86/kernel/cpu/bugs.c | 7 +++---- |
| 2 files changed, 15 insertions(+), 11 deletions(-) |
| |
| --- a/arch/x86/kernel/cpu/amd.c |
| +++ b/arch/x86/kernel/cpu/amd.c |
| @@ -1247,16 +1247,21 @@ 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); |
| - /* 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 |
| + case 0x19: |
| + /* Poke the MSR bit on Zen3/4 to check its presence. */ |
| + 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; |
| + } |
| } |
| |
| static void zenbleed_check_cpu(void *unused) |
| --- a/arch/x86/kernel/cpu/bugs.c |
| +++ b/arch/x86/kernel/cpu/bugs.c |
| @@ -2383,14 +2383,13 @@ static void __init srso_select_mitigatio |
| * 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); |
| } |
| |
| @@ -2463,8 +2462,8 @@ static void __init srso_select_mitigatio |
| 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; |
| } |
| |