162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci#ifndef __ASM_ASM_EXTABLE_H
362306a36Sopenharmony_ci#define __ASM_ASM_EXTABLE_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#define EX_TYPE_NONE			0
662306a36Sopenharmony_ci#define EX_TYPE_FIXUP			1
762306a36Sopenharmony_ci#define EX_TYPE_UACCESS_ERR_ZERO	2
862306a36Sopenharmony_ci#define EX_TYPE_BPF			3
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#ifdef __ASSEMBLY__
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#define __ASM_EXTABLE_RAW(insn, fixup, type, data)	\
1362306a36Sopenharmony_ci	.pushsection	__ex_table, "a";		\
1462306a36Sopenharmony_ci	.balign		4;				\
1562306a36Sopenharmony_ci	.long		((insn) - .);			\
1662306a36Sopenharmony_ci	.long		((fixup) - .);			\
1762306a36Sopenharmony_ci	.short		(type);				\
1862306a36Sopenharmony_ci	.short		(data);				\
1962306a36Sopenharmony_ci	.popsection;
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci	.macro		_asm_extable, insn, fixup
2262306a36Sopenharmony_ci	__ASM_EXTABLE_RAW(\insn, \fixup, EX_TYPE_FIXUP, 0)
2362306a36Sopenharmony_ci	.endm
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#else /* __ASSEMBLY__ */
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci#include <linux/bits.h>
2862306a36Sopenharmony_ci#include <linux/stringify.h>
2962306a36Sopenharmony_ci#include <asm/gpr-num.h>
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#define __ASM_EXTABLE_RAW(insn, fixup, type, data)	\
3262306a36Sopenharmony_ci	".pushsection	__ex_table, \"a\"\n"		\
3362306a36Sopenharmony_ci	".balign	4\n"				\
3462306a36Sopenharmony_ci	".long		((" insn ") - .)\n"		\
3562306a36Sopenharmony_ci	".long		((" fixup ") - .)\n"		\
3662306a36Sopenharmony_ci	".short		(" type ")\n"			\
3762306a36Sopenharmony_ci	".short		(" data ")\n"			\
3862306a36Sopenharmony_ci	".popsection\n"
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci#define _ASM_EXTABLE(insn, fixup)	\
4162306a36Sopenharmony_ci	__ASM_EXTABLE_RAW(#insn, #fixup, __stringify(EX_TYPE_FIXUP), "0")
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci#define EX_DATA_REG_ERR_SHIFT	0
4462306a36Sopenharmony_ci#define EX_DATA_REG_ERR		GENMASK(4, 0)
4562306a36Sopenharmony_ci#define EX_DATA_REG_ZERO_SHIFT	5
4662306a36Sopenharmony_ci#define EX_DATA_REG_ZERO	GENMASK(9, 5)
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci#define EX_DATA_REG(reg, gpr)						\
4962306a36Sopenharmony_ci	"((.L__gpr_num_" #gpr ") << " __stringify(EX_DATA_REG_##reg##_SHIFT) ")"
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci#define _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, zero)		\
5262306a36Sopenharmony_ci	__DEFINE_ASM_GPR_NUMS						\
5362306a36Sopenharmony_ci	__ASM_EXTABLE_RAW(#insn, #fixup, 				\
5462306a36Sopenharmony_ci			  __stringify(EX_TYPE_UACCESS_ERR_ZERO),	\
5562306a36Sopenharmony_ci			  "("						\
5662306a36Sopenharmony_ci			    EX_DATA_REG(ERR, err) " | "			\
5762306a36Sopenharmony_ci			    EX_DATA_REG(ZERO, zero)			\
5862306a36Sopenharmony_ci			  ")")
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci#define _ASM_EXTABLE_UACCESS_ERR(insn, fixup, err)			\
6162306a36Sopenharmony_ci	_ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, zero)
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci#endif /* __ASSEMBLY__ */
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci#endif /* __ASM_ASM_EXTABLE_H */
66