xref: /linux/arch/riscv/include/asm/asm-extable.h (revision e7d759f31ca295d589f7420719c311870bb3166f)
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_BPF			2
8 #define EX_TYPE_UACCESS_ERR_ZERO	3
9 #define EX_TYPE_LOAD_UNALIGNED_ZEROPAD	4
10 
11 #ifdef CONFIG_MMU
12 
13 #ifdef __ASSEMBLY__
14 
15 #define __ASM_EXTABLE_RAW(insn, fixup, type, data)	\
16 	.pushsection	__ex_table, "a";		\
17 	.balign		4;				\
18 	.long		((insn) - .);			\
19 	.long		((fixup) - .);			\
20 	.short		(type);				\
21 	.short		(data);				\
22 	.popsection;
23 
24 	.macro		_asm_extable, insn, fixup
25 	__ASM_EXTABLE_RAW(\insn, \fixup, EX_TYPE_FIXUP, 0)
26 	.endm
27 
28 #else /* __ASSEMBLY__ */
29 
30 #include <linux/bits.h>
31 #include <linux/stringify.h>
32 #include <asm/gpr-num.h>
33 
34 #define __ASM_EXTABLE_RAW(insn, fixup, type, data)	\
35 	".pushsection	__ex_table, \"a\"\n"		\
36 	".balign	4\n"				\
37 	".long		((" insn ") - .)\n"		\
38 	".long		((" fixup ") - .)\n"		\
39 	".short		(" type ")\n"			\
40 	".short		(" data ")\n"			\
41 	".popsection\n"
42 
43 #define _ASM_EXTABLE(insn, fixup)	\
44 	__ASM_EXTABLE_RAW(#insn, #fixup, __stringify(EX_TYPE_FIXUP), "0")
45 
46 #define EX_DATA_REG_ERR_SHIFT	0
47 #define EX_DATA_REG_ERR		GENMASK(4, 0)
48 #define EX_DATA_REG_ZERO_SHIFT	5
49 #define EX_DATA_REG_ZERO	GENMASK(9, 5)
50 
51 #define EX_DATA_REG_DATA_SHIFT	0
52 #define EX_DATA_REG_DATA	GENMASK(4, 0)
53 #define EX_DATA_REG_ADDR_SHIFT	5
54 #define EX_DATA_REG_ADDR	GENMASK(9, 5)
55 
56 #define EX_DATA_REG(reg, gpr)						\
57 	"((.L__gpr_num_" #gpr ") << " __stringify(EX_DATA_REG_##reg##_SHIFT) ")"
58 
59 #define _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, zero)		\
60 	__DEFINE_ASM_GPR_NUMS						\
61 	__ASM_EXTABLE_RAW(#insn, #fixup, 				\
62 			  __stringify(EX_TYPE_UACCESS_ERR_ZERO),	\
63 			  "("						\
64 			    EX_DATA_REG(ERR, err) " | "			\
65 			    EX_DATA_REG(ZERO, zero)			\
66 			  ")")
67 
68 #define _ASM_EXTABLE_UACCESS_ERR(insn, fixup, err)			\
69 	_ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, zero)
70 
71 #define _ASM_EXTABLE_LOAD_UNALIGNED_ZEROPAD(insn, fixup, data, addr)		\
72 	__DEFINE_ASM_GPR_NUMS							\
73 	__ASM_EXTABLE_RAW(#insn, #fixup,					\
74 			  __stringify(EX_TYPE_LOAD_UNALIGNED_ZEROPAD),		\
75 			  "("							\
76 			    EX_DATA_REG(DATA, data) " | "			\
77 			    EX_DATA_REG(ADDR, addr)				\
78 			  ")")
79 
80 #endif /* __ASSEMBLY__ */
81 
82 #else /* CONFIG_MMU */
83 	#define _ASM_EXTABLE_UACCESS_ERR(insn, fixup, err)
84 #endif /* CONFIG_MMU */
85 
86 #endif /* __ASM_ASM_EXTABLE_H */
87