1 /* SPDX-License-Identifier: GPL-2.0-only */
2 #ifndef __ASM_ASM_EXTABLE_H
3 #define __ASM_ASM_EXTABLE_H
4 
5 #define EX_TYPE_NONE			0
6 #define EX_TYPE_FIXUP			1
7 #define EX_TYPE_UACCESS_ERR_ZERO	2
8 
9 #ifdef __ASSEMBLY__
10 
11 #define __ASM_EXTABLE_RAW(insn, fixup, type, data)	\
12 	.pushsection	__ex_table, "a";		\
13 	.balign		4;				\
14 	.long		((insn) - .);			\
15 	.long		((fixup) - .);			\
16 	.short		(type);				\
17 	.short		(data);				\
18 	.popsection;
19 
20 	.macro		_asm_extable, insn, fixup
21 	__ASM_EXTABLE_RAW(\insn, \fixup, EX_TYPE_FIXUP, 0)
22 	.endm
23 
24 #else /* __ASSEMBLY__ */
25 
26 #include <linux/bits.h>
27 #include <linux/stringify.h>
28 #include <asm/gpr-num.h>
29 
30 #define __ASM_EXTABLE_RAW(insn, fixup, type, data)	\
31 	".pushsection	__ex_table, \"a\"\n"		\
32 	".balign	4\n"				\
33 	".long		((" insn ") - .)\n"		\
34 	".long		((" fixup ") - .)\n"		\
35 	".short		(" type ")\n"			\
36 	".short		(" data ")\n"			\
37 	".popsection\n"
38 
39 #define _ASM_EXTABLE(insn, fixup)	\
40 	__ASM_EXTABLE_RAW(#insn, #fixup, __stringify(EX_TYPE_FIXUP), "0")
41 
42 #define EX_DATA_REG_ERR_SHIFT	0
43 #define EX_DATA_REG_ERR		GENMASK(4, 0)
44 #define EX_DATA_REG_ZERO_SHIFT	5
45 #define EX_DATA_REG_ZERO	GENMASK(9, 5)
46 
47 #define EX_DATA_REG(reg, gpr)						\
48 	"((.L__gpr_num_" #gpr ") << " __stringify(EX_DATA_REG_##reg##_SHIFT) ")"
49 
50 #define _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, zero)		\
51 	__DEFINE_ASM_GPR_NUMS						\
52 	__ASM_EXTABLE_RAW(#insn, #fixup, 				\
53 			  __stringify(EX_TYPE_UACCESS_ERR_ZERO),	\
54 			  "("						\
55 			    EX_DATA_REG(ERR, err) " | "			\
56 			    EX_DATA_REG(ZERO, zero)			\
57 			  ")")
58 
59 #define _ASM_EXTABLE_UACCESS_ERR(insn, fixup, err)			\
60 	_ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, zero)
61 
62 #endif /* __ASSEMBLY__ */
63 
64 #endif /* __ASM_ASM_EXTABLE_H */
65