| 1 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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
|
| 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
|
| 136 |
|
| 137 | #endif
|