1 #ifndef _ASM_X86_JUMP_LABEL_H 2 #define _ASM_X86_JUMP_LABEL_H 3 4 #ifndef __ASSEMBLY__ 5 6 #include <linux/stringify.h> 7 #include <linux/types.h> 8 #include <asm/nops.h> 9 #include <asm/asm.h> 10 11 #define JUMP_LABEL_NOP_SIZE 5 12 13 #ifdef CONFIG_X86_64 14 # define STATIC_KEY_INIT_NOP P6_NOP5_ATOMIC 15 #else 16 # define STATIC_KEY_INIT_NOP GENERIC_NOP5_ATOMIC 17 #endif 18 19 static __always_inline bool arch_static_branch(struct static_key *key, bool branch) 20 { 21 asm_volatile_goto("1:" 22 ".byte " __stringify(STATIC_KEY_INIT_NOP) "\n\t" 23 ".pushsection __jump_table, \"aw\" \n\t" 24 _ASM_ALIGN "\n\t" 25 _ASM_PTR "1b, %l[l_yes], %c0 + %c1 \n\t" 26 ".popsection \n\t" 27 : : "i" (key), "i" (branch) : : l_yes); 28 29 return false; 30 l_yes: 31 return true; 32 } 33 34 static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch) 35 { 36 asm_volatile_goto("1:" 37 ".byte 0xe9\n\t .long %l[l_yes] - 2f\n\t" 38 "2:\n\t" 39 ".pushsection __jump_table, \"aw\" \n\t" 40 _ASM_ALIGN "\n\t" 41 _ASM_PTR "1b, %l[l_yes], %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 #ifdef CONFIG_X86_64 51 typedef u64 jump_label_t; 52 #else 53 typedef u32 jump_label_t; 54 #endif 55 56 struct jump_entry { 57 jump_label_t code; 58 jump_label_t target; 59 jump_label_t key; 60 }; 61 62 #endif /* __ASSEMBLY__ */ 63 #endif 64