]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
x86/amd: Use IBPB for firmware calls
authorPeter Zijlstra <peterz@infradead.org>
Mon, 18 Jul 2022 11:41:37 +0000 (13:41 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 29 Jul 2022 15:19:27 +0000 (17:19 +0200)
commit 28a99e95f55c61855983d36a88c05c178d966bb7 upstream.

On AMD IBRS does not prevent Retbleed; as such use IBPB before a
firmware call to flush the branch history state.

And because in order to do an EFI call, the kernel maps a whole lot of
the kernel page table into the EFI page table, do an IBPB just in case
in order to prevent the scenario of poisoning the BTB and causing an EFI
call using the unprotected RET there.

  [ bp: Massage. ]

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lore.kernel.org/r/20220715194550.793957-1-cascardo@canonical.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/include/asm/cpufeatures.h
arch/x86/include/asm/nospec-branch.h
arch/x86/kernel/cpu/bugs.c

index e077f4fe7c6d404c0200216e2f370c1b00531427..2a51ee2f5a0f0095cb2ea4cc4f7edfe1e164ae5c 100644 (file)
 #define X86_FEATURE_RETPOLINE_LFENCE   (11*32+13) /* "" Use LFENCE for Spectre variant 2 */
 #define X86_FEATURE_RETHUNK            (11*32+14) /* "" Use REturn THUNK */
 #define X86_FEATURE_UNRET              (11*32+15) /* "" AMD BTB untrain return */
+#define X86_FEATURE_USE_IBPB_FW                (11*32+16) /* "" Use IBPB during runtime firmware calls */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
 #define X86_FEATURE_AVX512_BF16                (12*32+ 5) /* AVX512 BFLOAT16 instructions */
index 6f2adaf53f46780f3c92f3f7171a81fda253219b..c3e8e50633ea2f6e4adcb4fe85f2c4541b27560a 100644 (file)
@@ -298,6 +298,8 @@ do {                                                                        \
        alternative_msr_write(MSR_IA32_SPEC_CTRL,                       \
                              spec_ctrl_current() | SPEC_CTRL_IBRS,     \
                              X86_FEATURE_USE_IBRS_FW);                 \
+       alternative_msr_write(MSR_IA32_PRED_CMD, PRED_CMD_IBPB,         \
+                             X86_FEATURE_USE_IBPB_FW);                 \
 } while (0)
 
 #define firmware_restrict_branch_speculation_end()                     \
index c2f78f893d9816b6026d3cb256c4ca07e89c6f69..7896b67dda420f089df0998cec9231357d855f82 100644 (file)
@@ -1475,7 +1475,16 @@ static void __init spectre_v2_select_mitigation(void)
         * the CPU supports Enhanced IBRS, kernel might un-intentionally not
         * enable IBRS around firmware calls.
         */
-       if (boot_cpu_has(X86_FEATURE_IBRS) && !spectre_v2_in_ibrs_mode(mode)) {
+       if (boot_cpu_has_bug(X86_BUG_RETBLEED) &&
+           (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
+            boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)) {
+
+               if (retbleed_cmd != RETBLEED_CMD_IBPB) {
+                       setup_force_cpu_cap(X86_FEATURE_USE_IBPB_FW);
+                       pr_info("Enabling Speculation Barrier for firmware calls\n");
+               }
+
+       } else if (boot_cpu_has(X86_FEATURE_IBRS) && !spectre_v2_in_ibrs_mode(mode)) {
                setup_force_cpu_cap(X86_FEATURE_USE_IBRS_FW);
                pr_info("Enabling Restricted Speculation for firmware calls\n");
        }