asm-extable.h 3.5 KB

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