1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _ASM_X86_JUMP_LABEL_H 3 #define _ASM_X86_JUMP_LABEL_H 4 5 #define HAVE_JUMP_LABEL_BATCH 6 7 #define JUMP_LABEL_NOP_SIZE 5 8 9 #include <asm/asm.h> 10 #include <asm/nops.h> 11 12 #ifndef __ASSEMBLY__ 13 14 #include <linux/stringify.h> 15 #include <linux/types.h> 16 17 static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch) 18 { 19 asm_volatile_goto("1:" 20 ".byte " __stringify(BYTES_NOP5) "\n\t" 21 ".pushsection __jump_table, \"aw\" \n\t" 22 _ASM_ALIGN "\n\t" 23 ".long 1b - ., %l[l_yes] - . \n\t" 24 _ASM_PTR "%c0 + %c1 - .\n\t" 25 ".popsection \n\t" 26 : : "i" (key), "i" (branch) : : l_yes); 27 28 return false; 29 l_yes: 30 return true; 31 } 32 33 static __always_inline bool arch_static_branch_jump(struct static_key * const key, const bool branch) 34 { 35 asm_volatile_goto("1:" 36 ".byte 0xe9\n\t .long %l[l_yes] - 2f\n\t" 37 "2:\n\t" 38 ".pushsection __jump_table, \"aw\" \n\t" 39 _ASM_ALIGN "\n\t" 40 ".long 1b - ., %l[l_yes] - . \n\t" 41 _ASM_PTR "%c0 + %c1 - .\n\t" 42 ".popsection \n\t" 43 : : "i" (key), "i" (branch) : : l_yes); 44 45 return false; 46 l_yes: 47 return true; 48 } 49 50 #else /* __ASSEMBLY__ */ 51 52 .macro STATIC_JUMP_IF_TRUE target, key, def 53 .Lstatic_jump_\@: 54 .if \def 55 /* Equivalent to "jmp.d32 \target" */ 56 .byte 0xe9 57 .long \target - .Lstatic_jump_after_\@ 58 .Lstatic_jump_after_\@: 59 .else 60 .byte BYTES_NOP5 61 .endif 62 .pushsection __jump_table, "aw" 63 _ASM_ALIGN 64 .long .Lstatic_jump_\@ - ., \target - . 65 _ASM_PTR \key - . 66 .popsection 67 .endm 68 69 .macro STATIC_JUMP_IF_FALSE target, key, def 70 .Lstatic_jump_\@: 71 .if \def 72 .byte BYTES_NOP5 73 .else 74 /* Equivalent to "jmp.d32 \target" */ 75 .byte 0xe9 76 .long \target - .Lstatic_jump_after_\@ 77 .Lstatic_jump_after_\@: 78 .endif 79 .pushsection __jump_table, "aw" 80 _ASM_ALIGN 81 .long .Lstatic_jump_\@ - ., \target - . 82 _ASM_PTR \key + 1 - . 83 .popsection 84 .endm 85 86 #endif /* __ASSEMBLY__ */ 87 88 #endif 89