Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 #ifndef __ASM_ASM_EXTABLE_H
0003 #define __ASM_ASM_EXTABLE_H
0004 
0005 #include <linux/bits.h>
0006 #include <asm/gpr-num.h>
0007 
0008 #define EX_TYPE_NONE            0
0009 #define EX_TYPE_BPF         1
0010 #define EX_TYPE_UACCESS_ERR_ZERO    2
0011 #define EX_TYPE_KACCESS_ERR_ZERO    3
0012 #define EX_TYPE_LOAD_UNALIGNED_ZEROPAD  4
0013 
0014 /* Data fields for EX_TYPE_UACCESS_ERR_ZERO */
0015 #define EX_DATA_REG_ERR_SHIFT   0
0016 #define EX_DATA_REG_ERR     GENMASK(4, 0)
0017 #define EX_DATA_REG_ZERO_SHIFT  5
0018 #define EX_DATA_REG_ZERO    GENMASK(9, 5)
0019 
0020 /* Data fields for EX_TYPE_LOAD_UNALIGNED_ZEROPAD */
0021 #define EX_DATA_REG_DATA_SHIFT  0
0022 #define EX_DATA_REG_DATA    GENMASK(4, 0)
0023 #define EX_DATA_REG_ADDR_SHIFT  5
0024 #define EX_DATA_REG_ADDR    GENMASK(9, 5)
0025 
0026 #ifdef __ASSEMBLY__
0027 
0028 #define __ASM_EXTABLE_RAW(insn, fixup, type, data)  \
0029     .pushsection    __ex_table, "a";        \
0030     .align      2;              \
0031     .long       ((insn) - .);           \
0032     .long       ((fixup) - .);          \
0033     .short      (type);             \
0034     .short      (data);             \
0035     .popsection;
0036 
0037 #define EX_DATA_REG(reg, gpr)   \
0038     (.L__gpr_num_##gpr << EX_DATA_REG_##reg##_SHIFT)
0039 
0040 #define _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, zero)       \
0041     __ASM_EXTABLE_RAW(insn, fixup,                  \
0042               EX_TYPE_UACCESS_ERR_ZERO,         \
0043               (                     \
0044                 EX_DATA_REG(ERR, err) |         \
0045                 EX_DATA_REG(ZERO, zero)         \
0046               ))
0047 
0048 #define _ASM_EXTABLE_UACCESS_ERR(insn, fixup, err)          \
0049     _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, wzr)
0050 
0051 #define _ASM_EXTABLE_UACCESS(insn, fixup)               \
0052     _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, wzr, wzr)
0053 
0054 /*
0055  * Create an exception table entry for uaccess `insn`, which will branch to `fixup`
0056  * when an unhandled fault is taken.
0057  */
0058     .macro          _asm_extable_uaccess, insn, fixup
0059     _ASM_EXTABLE_UACCESS(\insn, \fixup)
0060     .endm
0061 
0062 /*
0063  * Create an exception table entry for `insn` if `fixup` is provided. Otherwise
0064  * do nothing.
0065  */
0066     .macro      _cond_uaccess_extable, insn, fixup
0067     .ifnc           \fixup,
0068     _asm_extable_uaccess    \insn, \fixup
0069     .endif
0070     .endm
0071 
0072 #else /* __ASSEMBLY__ */
0073 
0074 #include <linux/stringify.h>
0075 
0076 #define __ASM_EXTABLE_RAW(insn, fixup, type, data)  \
0077     ".pushsection   __ex_table, \"a\"\n"        \
0078     ".align     2\n"                \
0079     ".long      ((" insn ") - .)\n"     \
0080     ".long      ((" fixup ") - .)\n"        \
0081     ".short     (" type ")\n"           \
0082     ".short     (" data ")\n"           \
0083     ".popsection\n"
0084 
0085 #define EX_DATA_REG(reg, gpr)                       \
0086     "((.L__gpr_num_" #gpr ") << " __stringify(EX_DATA_REG_##reg##_SHIFT) ")"
0087 
0088 #define _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, zero)       \
0089     __DEFINE_ASM_GPR_NUMS                       \
0090     __ASM_EXTABLE_RAW(#insn, #fixup,                \
0091               __stringify(EX_TYPE_UACCESS_ERR_ZERO),    \
0092               "("                       \
0093                 EX_DATA_REG(ERR, err) " | "         \
0094                 EX_DATA_REG(ZERO, zero)         \
0095               ")")
0096 
0097 #define _ASM_EXTABLE_KACCESS_ERR_ZERO(insn, fixup, err, zero)       \
0098     __DEFINE_ASM_GPR_NUMS                       \
0099     __ASM_EXTABLE_RAW(#insn, #fixup,                \
0100               __stringify(EX_TYPE_KACCESS_ERR_ZERO),    \
0101               "("                       \
0102                 EX_DATA_REG(ERR, err) " | "         \
0103                 EX_DATA_REG(ZERO, zero)         \
0104               ")")
0105 
0106 #define _ASM_EXTABLE_UACCESS_ERR(insn, fixup, err)          \
0107     _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, err, wzr)
0108 
0109 #define _ASM_EXTABLE_UACCESS(insn, fixup)               \
0110     _ASM_EXTABLE_UACCESS_ERR_ZERO(insn, fixup, wzr, wzr)
0111 
0112 #define _ASM_EXTABLE_KACCESS_ERR(insn, fixup, err)          \
0113     _ASM_EXTABLE_KACCESS_ERR_ZERO(insn, fixup, err, wzr)
0114 
0115 #define _ASM_EXTABLE_LOAD_UNALIGNED_ZEROPAD(insn, fixup, data, addr)        \
0116     __DEFINE_ASM_GPR_NUMS                           \
0117     __ASM_EXTABLE_RAW(#insn, #fixup,                    \
0118               __stringify(EX_TYPE_LOAD_UNALIGNED_ZEROPAD),      \
0119               "("                           \
0120                 EX_DATA_REG(DATA, data) " | "           \
0121                 EX_DATA_REG(ADDR, addr)             \
0122               ")")
0123 
0124 #endif /* __ASSEMBLY__ */
0125 
0126 #endif /* __ASM_ASM_EXTABLE_H */