LCOV - code coverage report
Current view: top level - arch/x86/include/asm - nospec-branch.h (source / functions) Hit Total Coverage
Test: landlock.info Lines: 10 17 58.8 %
Date: 2021-04-22 12:43:58 Functions: 1 2 50.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: GPL-2.0 */
       2             : 
       3             : #ifndef _ASM_X86_NOSPEC_BRANCH_H_
       4             : #define _ASM_X86_NOSPEC_BRANCH_H_
       5             : 
       6             : #include <linux/static_key.h>
       7             : #include <linux/objtool.h>
       8             : 
       9             : #include <asm/alternative.h>
      10             : #include <asm/alternative-asm.h>
      11             : #include <asm/cpufeatures.h>
      12             : #include <asm/msr-index.h>
      13             : #include <asm/unwind_hints.h>
      14             : 
      15             : /*
      16             :  * Fill the CPU return stack buffer.
      17             :  *
      18             :  * Each entry in the RSB, if used for a speculative 'ret', contains an
      19             :  * infinite 'pause; lfence; jmp' loop to capture speculative execution.
      20             :  *
      21             :  * This is required in various cases for retpoline and IBRS-based
      22             :  * mitigations for the Spectre variant 2 vulnerability. Sometimes to
      23             :  * eliminate potentially bogus entries from the RSB, and sometimes
      24             :  * purely to ensure that it doesn't get empty, which on some CPUs would
      25             :  * allow predictions from other (unwanted!) sources to be used.
      26             :  *
      27             :  * We define a CPP macro such that it can be used from both .S files and
      28             :  * inline assembly. It's possible to do a .macro and then include that
      29             :  * from C via asm(".include <asm/nospec-branch.h>") but let's not go there.
      30             :  */
      31             : 
      32             : #define RSB_CLEAR_LOOPS         32      /* To forcibly overwrite all entries */
      33             : 
      34             : /*
      35             :  * Google experimented with loop-unrolling and this turned out to be
      36             :  * the optimal version — two calls, each with their own speculation
      37             :  * trap should their return address end up getting used, in a loop.
      38             :  */
      39             : #define __FILL_RETURN_BUFFER(reg, nr, sp)       \
      40             :         mov     $(nr/2), reg;                   \
      41             : 771:                                            \
      42             :         ANNOTATE_INTRA_FUNCTION_CALL;           \
      43             :         call    772f;                           \
      44             : 773:    /* speculation trap */                  \
      45             :         UNWIND_HINT_EMPTY;                      \
      46             :         pause;                                  \
      47             :         lfence;                                 \
      48             :         jmp     773b;                           \
      49             : 772:                                            \
      50             :         ANNOTATE_INTRA_FUNCTION_CALL;           \
      51             :         call    774f;                           \
      52             : 775:    /* speculation trap */                  \
      53             :         UNWIND_HINT_EMPTY;                      \
      54             :         pause;                                  \
      55             :         lfence;                                 \
      56             :         jmp     775b;                           \
      57             : 774:                                            \
      58             :         add     $(BITS_PER_LONG/8) * 2, sp;     \
      59             :         dec     reg;                            \
      60             :         jnz     771b;
      61             : 
      62             : #ifdef __ASSEMBLY__
      63             : 
      64             : /*
      65             :  * This should be used immediately before an indirect jump/call. It tells
      66             :  * objtool the subsequent indirect jump/call is vouched safe for retpoline
      67             :  * builds.
      68             :  */
      69             : .macro ANNOTATE_RETPOLINE_SAFE
      70             :         .Lannotate_\@:
      71             :         .pushsection .discard.retpoline_safe
      72             :         _ASM_PTR .Lannotate_\@
      73             :         .popsection
      74             : .endm
      75             : 
      76             : /*
      77             :  * JMP_NOSPEC and CALL_NOSPEC macros can be used instead of a simple
      78             :  * indirect jmp/call which may be susceptible to the Spectre variant 2
      79             :  * attack.
      80             :  */
      81             : .macro JMP_NOSPEC reg:req
      82             : #ifdef CONFIG_RETPOLINE
      83             :         ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), \
      84             :                       __stringify(jmp __x86_retpoline_\reg), X86_FEATURE_RETPOLINE, \
      85             :                       __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; jmp *%\reg), X86_FEATURE_RETPOLINE_AMD
      86             : #else
      87             :         jmp     *%\reg
      88             : #endif
      89             : .endm
      90             : 
      91             : .macro CALL_NOSPEC reg:req
      92             : #ifdef CONFIG_RETPOLINE
      93             :         ALTERNATIVE_2 __stringify(ANNOTATE_RETPOLINE_SAFE; call *%\reg), \
      94             :                       __stringify(call __x86_retpoline_\reg), X86_FEATURE_RETPOLINE, \
      95             :                       __stringify(lfence; ANNOTATE_RETPOLINE_SAFE; call *%\reg), X86_FEATURE_RETPOLINE_AMD
      96             : #else
      97             :         call    *%\reg
      98             : #endif
      99             : .endm
     100             : 
     101             :  /*
     102             :   * A simpler FILL_RETURN_BUFFER macro. Don't make people use the CPP
     103             :   * monstrosity above, manually.
     104             :   */
     105             : .macro FILL_RETURN_BUFFER reg:req nr:req ftr:req
     106             : #ifdef CONFIG_RETPOLINE
     107             :         ALTERNATIVE "jmp .Lskip_rsb_\@", "", \ftr
     108             :         __FILL_RETURN_BUFFER(\reg,\nr,%_ASM_SP)
     109             : .Lskip_rsb_\@:
     110             : #endif
     111             : .endm
     112             : 
     113             : #else /* __ASSEMBLY__ */
     114             : 
     115             : #define ANNOTATE_RETPOLINE_SAFE                                 \
     116             :         "999:\n\t"                                            \
     117             :         ".pushsection .discard.retpoline_safe\n\t"            \
     118             :         _ASM_PTR " 999b\n\t"                                  \
     119             :         ".popsection\n\t"
     120             : 
     121             : #ifdef CONFIG_RETPOLINE
     122             : #ifdef CONFIG_X86_64
     123             : 
     124             : /*
     125             :  * Inline asm uses the %V modifier which is only in newer GCC
     126             :  * which is ensured when CONFIG_RETPOLINE is defined.
     127             :  */
     128             : # define CALL_NOSPEC                                            \
     129             :         ALTERNATIVE_2(                                          \
     130             :         ANNOTATE_RETPOLINE_SAFE                                 \
     131             :         "call *%[thunk_target]\n",                            \
     132             :         "call __x86_retpoline_%V[thunk_target]\n",            \
     133             :         X86_FEATURE_RETPOLINE,                                  \
     134             :         "lfence;\n"                                           \
     135             :         ANNOTATE_RETPOLINE_SAFE                                 \
     136             :         "call *%[thunk_target]\n",                            \
     137             :         X86_FEATURE_RETPOLINE_AMD)
     138             : 
     139             : # define THUNK_TARGET(addr) [thunk_target] "r" (addr)
     140             : 
     141             : #else /* CONFIG_X86_32 */
     142             : /*
     143             :  * For i386 we use the original ret-equivalent retpoline, because
     144             :  * otherwise we'll run out of registers. We don't care about CET
     145             :  * here, anyway.
     146             :  */
     147             : # define CALL_NOSPEC                                            \
     148             :         ALTERNATIVE_2(                                          \
     149             :         ANNOTATE_RETPOLINE_SAFE                                 \
     150             :         "call *%[thunk_target]\n",                            \
     151             :         "       jmp    904f;\n"                                       \
     152             :         "       .align 16\n"                                  \
     153             :         "901:      call   903f;\n"                                    \
     154             :         "902:      pause;\n"                                  \
     155             :         "          lfence;\n"                                 \
     156             :         "       jmp    902b;\n"                                       \
     157             :         "       .align 16\n"                                  \
     158             :         "903:      lea    4(%%esp), %%esp;\n"                 \
     159             :         "       pushl  %[thunk_target];\n"                    \
     160             :         "       ret;\n"                                               \
     161             :         "       .align 16\n"                                  \
     162             :         "904:      call   901b;\n",                           \
     163             :         X86_FEATURE_RETPOLINE,                                  \
     164             :         "lfence;\n"                                           \
     165             :         ANNOTATE_RETPOLINE_SAFE                                 \
     166             :         "call *%[thunk_target]\n",                            \
     167             :         X86_FEATURE_RETPOLINE_AMD)
     168             : 
     169             : # define THUNK_TARGET(addr) [thunk_target] "rm" (addr)
     170             : #endif
     171             : #else /* No retpoline for C / inline asm */
     172             : # define CALL_NOSPEC "call *%[thunk_target]\n"
     173             : # define THUNK_TARGET(addr) [thunk_target] "rm" (addr)
     174             : #endif
     175             : 
     176             : /* The Spectre V2 mitigation variants */
     177             : enum spectre_v2_mitigation {
     178             :         SPECTRE_V2_NONE,
     179             :         SPECTRE_V2_RETPOLINE_GENERIC,
     180             :         SPECTRE_V2_RETPOLINE_AMD,
     181             :         SPECTRE_V2_IBRS_ENHANCED,
     182             : };
     183             : 
     184             : /* The indirect branch speculation control variants */
     185             : enum spectre_v2_user_mitigation {
     186             :         SPECTRE_V2_USER_NONE,
     187             :         SPECTRE_V2_USER_STRICT,
     188             :         SPECTRE_V2_USER_STRICT_PREFERRED,
     189             :         SPECTRE_V2_USER_PRCTL,
     190             :         SPECTRE_V2_USER_SECCOMP,
     191             : };
     192             : 
     193             : /* The Speculative Store Bypass disable variants */
     194             : enum ssb_mitigation {
     195             :         SPEC_STORE_BYPASS_NONE,
     196             :         SPEC_STORE_BYPASS_DISABLE,
     197             :         SPEC_STORE_BYPASS_PRCTL,
     198             :         SPEC_STORE_BYPASS_SECCOMP,
     199             : };
     200             : 
     201             : extern char __indirect_thunk_start[];
     202             : extern char __indirect_thunk_end[];
     203             : 
     204             : static __always_inline
     205           0 : void alternative_msr_write(unsigned int msr, u64 val, unsigned int feature)
     206             : {
     207           0 :         asm volatile(ALTERNATIVE("", "wrmsr", %c[feature])
     208             :                 : : "c" (msr),
     209             :                     "a" ((u32)val),
     210             :                     "d" ((u32)(val >> 32)),
     211             :                     [feature] "i" (feature)
     212             :                 : "memory");
     213             : }
     214             : 
     215           0 : static inline void indirect_branch_prediction_barrier(void)
     216             : {
     217           0 :         u64 val = PRED_CMD_IBPB;
     218             : 
     219           0 :         alternative_msr_write(MSR_IA32_PRED_CMD, val, X86_FEATURE_USE_IBPB);
     220           0 : }
     221             : 
     222             : /* The Intel SPEC CTRL MSR base value cache */
     223             : extern u64 x86_spec_ctrl_base;
     224             : 
     225             : /*
     226             :  * With retpoline, we must use IBRS to restrict branch prediction
     227             :  * before calling into firmware.
     228             :  *
     229             :  * (Implemented as CPP macros due to header hell.)
     230             :  */
     231             : #define firmware_restrict_branch_speculation_start()                    \
     232             : do {                                                                    \
     233             :         u64 val = x86_spec_ctrl_base | SPEC_CTRL_IBRS;                  \
     234             :                                                                         \
     235             :         preempt_disable();                                              \
     236             :         alternative_msr_write(MSR_IA32_SPEC_CTRL, val,                  \
     237             :                               X86_FEATURE_USE_IBRS_FW);                 \
     238             : } while (0)
     239             : 
     240             : #define firmware_restrict_branch_speculation_end()                      \
     241             : do {                                                                    \
     242             :         u64 val = x86_spec_ctrl_base;                                   \
     243             :                                                                         \
     244             :         alternative_msr_write(MSR_IA32_SPEC_CTRL, val,                  \
     245             :                               X86_FEATURE_USE_IBRS_FW);                 \
     246             :         preempt_enable();                                               \
     247             : } while (0)
     248             : 
     249             : DECLARE_STATIC_KEY_FALSE(switch_to_cond_stibp);
     250             : DECLARE_STATIC_KEY_FALSE(switch_mm_cond_ibpb);
     251             : DECLARE_STATIC_KEY_FALSE(switch_mm_always_ibpb);
     252             : 
     253             : DECLARE_STATIC_KEY_FALSE(mds_user_clear);
     254             : DECLARE_STATIC_KEY_FALSE(mds_idle_clear);
     255             : 
     256             : #include <asm/segment.h>
     257             : 
     258             : /**
     259             :  * mds_clear_cpu_buffers - Mitigation for MDS and TAA vulnerability
     260             :  *
     261             :  * This uses the otherwise unused and obsolete VERW instruction in
     262             :  * combination with microcode which triggers a CPU buffer flush when the
     263             :  * instruction is executed.
     264             :  */
     265      442589 : static __always_inline void mds_clear_cpu_buffers(void)
     266             : {
     267      442589 :         static const u16 ds = __KERNEL_DS;
     268             : 
     269             :         /*
     270             :          * Has to be the memory-operand variant because only that
     271             :          * guarantees the CPU buffer flush functionality according to
     272             :          * documentation. The register-operand variant does not.
     273             :          * Works with any segment selector, but a valid writable
     274             :          * data segment is the fastest variant.
     275             :          *
     276             :          * "cc" clobber is required because VERW modifies ZF.
     277             :          */
     278      442589 :         asm volatile("verw %[ds]" : : [ds] "m" (ds) : "cc");
     279      442605 : }
     280             : 
     281             : /**
     282             :  * mds_user_clear_cpu_buffers - Mitigation for MDS and TAA vulnerability
     283             :  *
     284             :  * Clear CPU buffers if the corresponding static key is enabled
     285             :  */
     286      442589 : static __always_inline void mds_user_clear_cpu_buffers(void)
     287             : {
     288      442589 :         if (static_branch_likely(&mds_user_clear))
     289      442589 :                 mds_clear_cpu_buffers();
     290             : }
     291             : 
     292             : /**
     293             :  * mds_idle_clear_cpu_buffers - Mitigation for MDS vulnerability
     294             :  *
     295             :  * Clear CPU buffers if the corresponding static key is enabled
     296             :  */
     297       51718 : static inline void mds_idle_clear_cpu_buffers(void)
     298             : {
     299       51718 :         if (static_branch_likely(&mds_idle_clear))
     300           0 :                 mds_clear_cpu_buffers();
     301       51719 : }
     302             : 
     303             : #endif /* __ASSEMBLY__ */
     304             : 
     305             : /*
     306             :  * Below is used in the eBPF JIT compiler and emits the byte sequence
     307             :  * for the following assembly:
     308             :  *
     309             :  * With retpolines configured:
     310             :  *
     311             :  *    callq do_rop
     312             :  *  spec_trap:
     313             :  *    pause
     314             :  *    lfence
     315             :  *    jmp spec_trap
     316             :  *  do_rop:
     317             :  *    mov %rcx,(%rsp) for x86_64
     318             :  *    mov %edx,(%esp) for x86_32
     319             :  *    retq
     320             :  *
     321             :  * Without retpolines configured:
     322             :  *
     323             :  *    jmp *%rcx for x86_64
     324             :  *    jmp *%edx for x86_32
     325             :  */
     326             : #ifdef CONFIG_RETPOLINE
     327             : # ifdef CONFIG_X86_64
     328             : #  define RETPOLINE_RCX_BPF_JIT_SIZE    17
     329             : #  define RETPOLINE_RCX_BPF_JIT()                               \
     330             : do {                                                            \
     331             :         EMIT1_off32(0xE8, 7);    /* callq do_rop */             \
     332             :         /* spec_trap: */                                        \
     333             :         EMIT2(0xF3, 0x90);       /* pause */                    \
     334             :         EMIT3(0x0F, 0xAE, 0xE8); /* lfence */                   \
     335             :         EMIT2(0xEB, 0xF9);       /* jmp spec_trap */            \
     336             :         /* do_rop: */                                           \
     337             :         EMIT4(0x48, 0x89, 0x0C, 0x24); /* mov %rcx,(%rsp) */    \
     338             :         EMIT1(0xC3);             /* retq */                     \
     339             : } while (0)
     340             : # else /* !CONFIG_X86_64 */
     341             : #  define RETPOLINE_EDX_BPF_JIT()                               \
     342             : do {                                                            \
     343             :         EMIT1_off32(0xE8, 7);    /* call do_rop */              \
     344             :         /* spec_trap: */                                        \
     345             :         EMIT2(0xF3, 0x90);       /* pause */                    \
     346             :         EMIT3(0x0F, 0xAE, 0xE8); /* lfence */                   \
     347             :         EMIT2(0xEB, 0xF9);       /* jmp spec_trap */            \
     348             :         /* do_rop: */                                           \
     349             :         EMIT3(0x89, 0x14, 0x24); /* mov %edx,(%esp) */          \
     350             :         EMIT1(0xC3);             /* ret */                      \
     351             : } while (0)
     352             : # endif
     353             : #else /* !CONFIG_RETPOLINE */
     354             : # ifdef CONFIG_X86_64
     355             : #  define RETPOLINE_RCX_BPF_JIT_SIZE    2
     356             : #  define RETPOLINE_RCX_BPF_JIT()                               \
     357             :         EMIT2(0xFF, 0xE1);       /* jmp *%rcx */
     358             : # else /* !CONFIG_X86_64 */
     359             : #  define RETPOLINE_EDX_BPF_JIT()                               \
     360             :         EMIT2(0xFF, 0xE2)        /* jmp *%edx */
     361             : # endif
     362             : #endif
     363             : 
     364             : #endif /* _ASM_X86_NOSPEC_BRANCH_H_ */

Generated by: LCOV version 1.14