x86/speculation: Disable RRSBA behavior
authorPawan Gupta <pawan.kumar.gupta@linux.intel.com>
Fri, 8 Jul 2022 20:36:09 +0000 (13:36 -0700)
committerBorislav Petkov <bp@suse.de>
Sat, 9 Jul 2022 11:12:45 +0000 (13:12 +0200)
Some Intel processors may use alternate predictors for RETs on
RSB-underflow. This condition may be vulnerable to Branch History
Injection (BHI) and intramode-BTI.

Kernel earlier added spectre_v2 mitigation modes (eIBRS+Retpolines,
eIBRS+LFENCE, Retpolines) which protect indirect CALLs and JMPs against
such attacks. However, on RSB-underflow, RET target prediction may
fallback to alternate predictors. As a result, RET's predicted target
may get influenced by branch history.

A new MSR_IA32_SPEC_CTRL bit (RRSBA_DIS_S) controls this fallback
behavior when in kernel mode. When set, RETs will not take predictions
from alternate predictors, hence mitigating RETs as well. Support for
this is enumerated by CPUID.7.2.EDX[RRSBA_CTRL] (bit2).

For spectre v2 mitigation, when a user selects a mitigation that
protects indirect CALLs and JMPs against BHI and intramode-BTI, set
RRSBA_DIS_S also to protect RETs for RSB-underflow case.

Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
arch/x86/include/asm/cpufeatures.h
arch/x86/include/asm/msr-index.h
arch/x86/kernel/cpu/bugs.c
arch/x86/kernel/cpu/scattered.c
tools/arch/x86/include/asm/msr-index.h

index 7e8099fd5ec1b8aae9f4d27458d962d8e6bc0a1b..00f5227c8459870d142a4dce759a997467448b50 100644 (file)
 #define X86_FEATURE_SGX1               (11*32+ 8) /* "" Basic SGX */
 #define X86_FEATURE_SGX2               (11*32+ 9) /* "" SGX Enclave Dynamic Memory Management (EDMM) */
 #define X86_FEATURE_ENTRY_IBPB         (11*32+10) /* "" Issue an IBPB on kernel entry */
-/* FREE!                               (11*32+11) */
+#define X86_FEATURE_RRSBA_CTRL         (11*32+11) /* "" RET prediction control */
 #define X86_FEATURE_RETPOLINE          (11*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */
 #define X86_FEATURE_RETPOLINE_LFENCE   (11*32+13) /* "" Use LFENCE for Spectre variant 2 */
 #define X86_FEATURE_RETHUNK            (11*32+14) /* "" Use REturn THUNK */
index 7b411d9a6efba1ca765ed13211b58330288985d3..cc615be27a54b2daf55352ab1d34c244ee0790c6 100644 (file)
@@ -51,6 +51,8 @@
 #define SPEC_CTRL_STIBP                        BIT(SPEC_CTRL_STIBP_SHIFT)      /* STIBP mask */
 #define SPEC_CTRL_SSBD_SHIFT           2          /* Speculative Store Bypass Disable bit */
 #define SPEC_CTRL_SSBD                 BIT(SPEC_CTRL_SSBD_SHIFT)       /* Speculative Store Bypass Disable */
+#define SPEC_CTRL_RRSBA_DIS_S_SHIFT    6          /* Disable RRSBA behavior */
+#define SPEC_CTRL_RRSBA_DIS_S          BIT(SPEC_CTRL_RRSBA_DIS_S_SHIFT)
 
 #define MSR_IA32_PRED_CMD              0x00000049 /* Prediction Command */
 #define PRED_CMD_IBPB                  BIT(0)     /* Indirect Branch Prediction Barrier */
                                                 * bit available to control VERW
                                                 * behavior.
                                                 */
+#define ARCH_CAP_RRSBA                 BIT(19) /*
+                                                * Indicates RET may use predictors
+                                                * other than the RSB. With eIBRS
+                                                * enabled predictions in kernel mode
+                                                * are restricted to targets in
+                                                * kernel.
+                                                */
 
 #define MSR_IA32_FLUSH_CMD             0x0000010b
 #define L1D_FLUSH                      BIT(0)  /*
index d26c57d98b9811529327e08c9451f214dbf25476..0dd04713434be38574073bf9631ddec9f9b21cda 100644 (file)
@@ -1318,6 +1318,22 @@ static enum spectre_v2_mitigation __init spectre_v2_select_retpoline(void)
        return SPECTRE_V2_RETPOLINE;
 }
 
+/* Disable in-kernel use of non-RSB RET predictors */
+static void __init spec_ctrl_disable_kernel_rrsba(void)
+{
+       u64 ia32_cap;
+
+       if (!boot_cpu_has(X86_FEATURE_RRSBA_CTRL))
+               return;
+
+       ia32_cap = x86_read_arch_cap_msr();
+
+       if (ia32_cap & ARCH_CAP_RRSBA) {
+               x86_spec_ctrl_base |= SPEC_CTRL_RRSBA_DIS_S;
+               write_spec_ctrl_current(x86_spec_ctrl_base, true);
+       }
+}
+
 static void __init spectre_v2_select_mitigation(void)
 {
        enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline();
@@ -1412,6 +1428,16 @@ static void __init spectre_v2_select_mitigation(void)
                break;
        }
 
+       /*
+        * Disable alternate RSB predictions in kernel when indirect CALLs and
+        * JMPs gets protection against BHI and Intramode-BTI, but RET
+        * prediction from a non-RSB predictor is still a risk.
+        */
+       if (mode == SPECTRE_V2_EIBRS_LFENCE ||
+           mode == SPECTRE_V2_EIBRS_RETPOLINE ||
+           mode == SPECTRE_V2_RETPOLINE)
+               spec_ctrl_disable_kernel_rrsba();
+
        spectre_v2_enabled = mode;
        pr_info("%s\n", spectre_v2_strings[mode]);
 
index dbaa8326d6f289d16a3dc431261c80fa063cebb7..fd44b54c90d50483646909e581e8cc7eaad67188 100644 (file)
@@ -27,6 +27,7 @@ static const struct cpuid_bit cpuid_bits[] = {
        { X86_FEATURE_APERFMPERF,       CPUID_ECX,  0, 0x00000006, 0 },
        { X86_FEATURE_EPB,              CPUID_ECX,  3, 0x00000006, 0 },
        { X86_FEATURE_INTEL_PPIN,       CPUID_EBX,  0, 0x00000007, 1 },
+       { X86_FEATURE_RRSBA_CTRL,       CPUID_EDX,  2, 0x00000007, 2 },
        { X86_FEATURE_CQM_LLC,          CPUID_EDX,  1, 0x0000000f, 0 },
        { X86_FEATURE_CQM_OCCUP_LLC,    CPUID_EDX,  0, 0x0000000f, 1 },
        { X86_FEATURE_CQM_MBM_TOTAL,    CPUID_EDX,  1, 0x0000000f, 1 },
index d27e0581b7777ba086a772453cc52f6afacdcdeb..2eab6a3a8a8c8f88604616102082711be549ca0d 100644 (file)
@@ -51,6 +51,8 @@
 #define SPEC_CTRL_STIBP                        BIT(SPEC_CTRL_STIBP_SHIFT)      /* STIBP mask */
 #define SPEC_CTRL_SSBD_SHIFT           2          /* Speculative Store Bypass Disable bit */
 #define SPEC_CTRL_SSBD                 BIT(SPEC_CTRL_SSBD_SHIFT)       /* Speculative Store Bypass Disable */
+#define SPEC_CTRL_RRSBA_DIS_S_SHIFT    6          /* Disable RRSBA behavior */
+#define SPEC_CTRL_RRSBA_DIS_S          BIT(SPEC_CTRL_RRSBA_DIS_S_SHIFT)
 
 #define MSR_IA32_PRED_CMD              0x00000049 /* Prediction Command */
 #define PRED_CMD_IBPB                  BIT(0)     /* Indirect Branch Prediction Barrier */
                                                 * bit available to control VERW
                                                 * behavior.
                                                 */
+#define ARCH_CAP_RRSBA                 BIT(19) /*
+                                                * Indicates RET may use predictors
+                                                * other than the RSB. With eIBRS
+                                                * enabled predictions in kernel mode
+                                                * are restricted to targets in
+                                                * kernel.
+                                                */
 
 #define MSR_IA32_FLUSH_CMD             0x0000010b
 #define L1D_FLUSH                      BIT(0)  /*