Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/asm: Add asm macros for static keys/jump labels

Unfortunately, we can only do this if HAVE_JUMP_LABEL. In
principle, we could do some serious surgery on the core jump
label infrastructure to keep the patch infrastructure available
on x86 on all builds, but that's probably not worth it.

Implementing the macros using a conditional branch as a fallback
seems like a bad idea: we'd have to clobber flags.

This limitation can't cause silent failures -- trying to include
asm/jump_label.h at all on a non-HAVE_JUMP_LABEL kernel will
error out. The macro's users are responsible for handling this
issue themselves.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/63aa45c4b692e8469e1876d6ccbb5da707972990.1447361906.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Andy Lutomirski and committed by
Ingo Molnar
2671c3e4 c2845433

+44 -8
+44 -8
arch/x86/include/asm/jump_label.h
··· 14 14 #error asm/jump_label.h included on a non-jump-label kernel 15 15 #endif 16 16 17 - #ifndef __ASSEMBLY__ 18 - 19 - #include <linux/stringify.h> 20 - #include <linux/types.h> 21 - #include <asm/nops.h> 22 - #include <asm/asm.h> 23 - 24 17 #define JUMP_LABEL_NOP_SIZE 5 25 18 26 19 #ifdef CONFIG_X86_64 ··· 21 28 #else 22 29 # define STATIC_KEY_INIT_NOP GENERIC_NOP5_ATOMIC 23 30 #endif 31 + 32 + #include <asm/asm.h> 33 + #include <asm/nops.h> 34 + 35 + #ifndef __ASSEMBLY__ 36 + 37 + #include <linux/stringify.h> 38 + #include <linux/types.h> 24 39 25 40 static __always_inline bool arch_static_branch(struct static_key *key, bool branch) 26 41 { ··· 73 72 jump_label_t key; 74 73 }; 75 74 76 - #endif /* __ASSEMBLY__ */ 75 + #else /* __ASSEMBLY__ */ 76 + 77 + .macro STATIC_JUMP_IF_TRUE target, key, def 78 + .Lstatic_jump_\@: 79 + .if \def 80 + /* Equivalent to "jmp.d32 \target" */ 81 + .byte 0xe9 82 + .long \target - .Lstatic_jump_after_\@ 83 + .Lstatic_jump_after_\@: 84 + .else 85 + .byte STATIC_KEY_INIT_NOP 86 + .endif 87 + .pushsection __jump_table, "aw" 88 + _ASM_ALIGN 89 + _ASM_PTR .Lstatic_jump_\@, \target, \key 90 + .popsection 91 + .endm 92 + 93 + .macro STATIC_JUMP_IF_FALSE target, key, def 94 + .Lstatic_jump_\@: 95 + .if \def 96 + .byte STATIC_KEY_INIT_NOP 97 + .else 98 + /* Equivalent to "jmp.d32 \target" */ 99 + .byte 0xe9 100 + .long \target - .Lstatic_jump_after_\@ 101 + .Lstatic_jump_after_\@: 102 + .endif 103 + .pushsection __jump_table, "aw" 104 + _ASM_ALIGN 105 + _ASM_PTR .Lstatic_jump_\@, \target, \key + 1 106 + .popsection 107 + .endm 108 + 109 + #endif /* __ASSEMBLY__ */ 110 + 77 111 #endif