xref: /linux/arch/s390/include/asm/jump_label.h (revision 805185b7c7a1069e407b6f7b3bc98e44d415f484)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_S390_JUMP_LABEL_H
3 #define _ASM_S390_JUMP_LABEL_H
4 
5 #define HAVE_JUMP_LABEL_BATCH
6 
7 #ifndef __ASSEMBLER__
8 
9 #include <linux/types.h>
10 #include <linux/stringify.h>
11 
12 #define JUMP_LABEL_NOP_SIZE 6
13 
14 #ifdef CONFIG_CC_IS_CLANG
15 #define JUMP_LABEL_STATIC_KEY_CONSTRAINT "i"
16 #elif __GNUC__ < 9
17 #define JUMP_LABEL_STATIC_KEY_CONSTRAINT "X"
18 #else
19 #define JUMP_LABEL_STATIC_KEY_CONSTRAINT "jdd"
20 #endif
21 
22 #define ARCH_JUMP_TABLE_ENTRY(key, label, local_label)	\
23 	".pushsection __jump_table,\"aw\"\n"		\
24 	".balign	8\n"				\
25 	".long	" local_label "-.," label "-.\n"	\
26 	".quad	" key "-.\n"				\
27 	".popsection\n"
28 
29 /*
30  * We use a brcl 0,<offset> instruction for jump labels so it
31  * can be easily distinguished from a hotpatch generated instruction.
32  */
33 #define ARCH_STATIC_BRANCH_ASM(key, label)	\
34 	"0:	brcl 0," label "\n"		\
35 	ARCH_JUMP_TABLE_ENTRY(key, label, "0b")
36 
37 #define ARCH_STATIC_BRANCH_JUMP_ASM(key, label)	\
38 	"0:	brcl 15," label "\n"		\
39 	ARCH_JUMP_TABLE_ENTRY(key, label, "0b")
40 
41 static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
42 {
43 	asm goto(ARCH_STATIC_BRANCH_ASM("%0+%1", "%l[label]")
44 		: : JUMP_LABEL_STATIC_KEY_CONSTRAINT (key), "i" (branch) : : label);
45 	return false;
46 label:
47 	return true;
48 }
49 
50 static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch)
51 {
52 	asm goto(ARCH_STATIC_BRANCH_JUMP_ASM("%0+%1", "%l[label]")
53 		: : JUMP_LABEL_STATIC_KEY_CONSTRAINT (key), "i" (branch) : : label);
54 	return false;
55 label:
56 	return true;
57 }
58 
59 #endif  /* __ASSEMBLER__ */
60 #endif
61