at v6.19 137 lines 3.9 kB view raw
1/* SPDX-License-Identifier: GPL-2.0-only */ 2#ifndef __ASM_ASM_EXTABLE_H 3#define __ASM_ASM_EXTABLE_H 4 5#include <linux/bits.h> 6#include <asm/gpr-num.h> 7 8#define EX_TYPE_NONE 0 9#define EX_TYPE_BPF 1 10#define EX_TYPE_UACCESS_ERR_ZERO 2 11#define EX_TYPE_KACCESS_ERR_ZERO 3 12#define EX_TYPE_UACCESS_CPY 4 13#define EX_TYPE_LOAD_UNALIGNED_ZEROPAD 5 14 15/* Data fields for EX_TYPE_UACCESS_ERR_ZERO */ 16#define EX_DATA_REG_ERR_SHIFT 0 17#define EX_DATA_REG_ERR GENMASK(4, 0) 18#define EX_DATA_REG_ZERO_SHIFT 5 19#define EX_DATA_REG_ZERO GENMASK(9, 5) 20 21/* Data fields for EX_TYPE_LOAD_UNALIGNED_ZEROPAD */ 22#define EX_DATA_REG_DATA_SHIFT 0 23#define EX_DATA_REG_DATA GENMASK(4, 0) 24#define EX_DATA_REG_ADDR_SHIFT 5 25#define EX_DATA_REG_ADDR GENMASK(9, 5) 26 27/* Data fields for EX_TYPE_UACCESS_CPY */ 28#define EX_DATA_UACCESS_WRITE BIT(0) 29 30#ifdef __ASSEMBLER__ 31 32#define __ASM_EXTABLE_RAW(insn, fixup, type, data) \ 33 .pushsection __ex_table, "a"; \ 34 .align 2; \ 35 .long ((insn) - .); \ 36 .long ((fixup) - .); \ 37 .short (type); \ 38 .short (data); \ 39 .popsection; 40 41#define EX_DATA_REG(reg, gpr) \ 42 (.L__gpr_num_##gpr << EX_DATA_REG_##reg##_SHIFT) 43 44#define _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, zero) \ 45 __ASM_EXTABLE_RAW(insn, fixup, \ 46 EX_TYPE_UACCESS_ERR_ZERO, \ 47 ( \ 48 EX_DATA_REG(ERR, err) | \ 49 EX_DATA_REG(ZERO, zero) \ 50 )) 51 52#define _ASM_EXTABLE_UACCESS_ERR(insn, fixup, err) \ 53 _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, wzr) 54 55#define _ASM_EXTABLE_UACCESS(insn, fixup) \ 56 _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, wzr, wzr) 57 58/* 59 * Create an exception table entry for uaccess `insn`, which will branch to `fixup` 60 * when an unhandled fault is taken. 61 */ 62 .macro _asm_extable_uaccess, insn, fixup 63 _ASM_EXTABLE_UACCESS(\insn, \fixup) 64 .endm 65 66/* 67 * Create an exception table entry for `insn` if `fixup` is provided. Otherwise 68 * do nothing. 69 */ 70 .macro _cond_uaccess_extable, insn, fixup 71 .ifnc \fixup, 72 _asm_extable_uaccess \insn, \fixup 73 .endif 74 .endm 75 76 .macro _asm_extable_uaccess_cpy, insn, fixup, uaccess_is_write 77 __ASM_EXTABLE_RAW(\insn, \fixup, EX_TYPE_UACCESS_CPY, \uaccess_is_write) 78 .endm 79 80#else /* __ASSEMBLER__ */ 81 82#include <linux/stringify.h> 83 84#define __ASM_EXTABLE_RAW(insn, fixup, type, data) \ 85 ".pushsection __ex_table, \"a\"\n" \ 86 ".align 2\n" \ 87 ".long ((" insn ") - .)\n" \ 88 ".long ((" fixup ") - .)\n" \ 89 ".short (" type ")\n" \ 90 ".short (" data ")\n" \ 91 ".popsection\n" 92 93#define EX_DATA_REG(reg, gpr) \ 94 "((.L__gpr_num_" #gpr ") << " __stringify(EX_DATA_REG_##reg##_SHIFT) ")" 95 96#define _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, zero) \ 97 __DEFINE_ASM_GPR_NUMS \ 98 __ASM_EXTABLE_RAW(#insn, #fixup, \ 99 __stringify(EX_TYPE_UACCESS_ERR_ZERO), \ 100 "(" \ 101 EX_DATA_REG(ERR, err) " | " \ 102 EX_DATA_REG(ZERO, zero) \ 103 ")") 104 105#define _ASM_EXTABLE_KACCESS_ERR_ZERO(insn, fixup, err, zero) \ 106 __DEFINE_ASM_GPR_NUMS \ 107 __ASM_EXTABLE_RAW(#insn, #fixup, \ 108 __stringify(EX_TYPE_KACCESS_ERR_ZERO), \ 109 "(" \ 110 EX_DATA_REG(ERR, err) " | " \ 111 EX_DATA_REG(ZERO, zero) \ 112 ")") 113 114#define _ASM_EXTABLE_UACCESS_ERR(insn, fixup, err) \ 115 _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, wzr) 116 117#define _ASM_EXTABLE_UACCESS(insn, fixup) \ 118 _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, wzr, wzr) 119 120#define _ASM_EXTABLE_KACCESS_ERR(insn, fixup, err) \ 121 _ASM_EXTABLE_KACCESS_ERR_ZERO(insn, fixup, err, wzr) 122 123#define _ASM_EXTABLE_KACCESS(insn, fixup) \ 124 _ASM_EXTABLE_KACCESS_ERR_ZERO(insn, fixup, wzr, wzr) 125 126#define _ASM_EXTABLE_LOAD_UNALIGNED_ZEROPAD(insn, fixup, data, addr) \ 127 __DEFINE_ASM_GPR_NUMS \ 128 __ASM_EXTABLE_RAW(#insn, #fixup, \ 129 __stringify(EX_TYPE_LOAD_UNALIGNED_ZEROPAD), \ 130 "(" \ 131 EX_DATA_REG(DATA, data) " | " \ 132 EX_DATA_REG(ADDR, addr) \ 133 ")") 134 135#endif /* __ASSEMBLER__ */ 136 137#endif /* __ASM_ASM_EXTABLE_H */