]> git.itanic.dy.fi Git - linux-stable/commitdiff
x86/srso: Tie SBPB bit setting to microcode patch detection
authorBorislav Petkov (AMD) <bp@alien8.de>
Mon, 7 Aug 2023 08:46:04 +0000 (10:46 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 Aug 2023 18:03:51 +0000 (20:03 +0200)
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
arch/x86/kernel/cpu/bugs.c

index 9842f2402978d7692dc2642fc5350edf7d58a432..7f0cf4a959c02f30d88edd1b7a8077dc8c161b32 100644 (file)
@@ -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)
index b4ac1f3d41b382e9a990d14edb653fcaedbe011b..d98f33ea57e4775d8ed1cced33c94e057874d909 100644 (file)
@@ -2383,14 +2383,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);
        }
 
@@ -2463,8 +2462,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;
 }