bug.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _ASM_POWERPC_BUG_H
  3. #define _ASM_POWERPC_BUG_H
  4. #ifdef __KERNEL__
  5. #include <asm/asm-compat.h>
  6. #include <asm/extable.h>
  7. #ifdef CONFIG_BUG
  8. #ifdef __ASSEMBLY__
  9. #include <asm/asm-offsets.h>
  10. #ifdef CONFIG_DEBUG_BUGVERBOSE
  11. .macro __EMIT_BUG_ENTRY addr,file,line,flags
  12. .section __bug_table,"aw"
  13. 5001: .4byte \addr - .
  14. .4byte 5002f - .
  15. .short \line, \flags
  16. .org 5001b+BUG_ENTRY_SIZE
  17. .previous
  18. .section .rodata,"a"
  19. 5002: .asciz "\file"
  20. .previous
  21. .endm
  22. #else
  23. .macro __EMIT_BUG_ENTRY addr,file,line,flags
  24. .section __bug_table,"aw"
  25. 5001: .4byte \addr - .
  26. .short \flags
  27. .org 5001b+BUG_ENTRY_SIZE
  28. .previous
  29. .endm
  30. #endif /* verbose */
  31. .macro EMIT_WARN_ENTRY addr,file,line,flags
  32. EX_TABLE(\addr,\addr+4)
  33. __EMIT_BUG_ENTRY \addr,\file,\line,\flags
  34. .endm
  35. .macro EMIT_BUG_ENTRY addr,file,line,flags
  36. .if \flags & 1 /* BUGFLAG_WARNING */
  37. .err /* Use EMIT_WARN_ENTRY for warnings */
  38. .endif
  39. __EMIT_BUG_ENTRY \addr,\file,\line,\flags
  40. .endm
  41. #else /* !__ASSEMBLY__ */
  42. /* _EMIT_BUG_ENTRY expects args %0,%1,%2,%3 to be FILE, LINE, flags and
  43. sizeof(struct bug_entry), respectively */
  44. #ifdef CONFIG_DEBUG_BUGVERBOSE
  45. #define _EMIT_BUG_ENTRY \
  46. ".section __bug_table,\"aw\"\n" \
  47. "2: .4byte 1b - .\n" \
  48. " .4byte %0 - .\n" \
  49. " .short %1, %2\n" \
  50. ".org 2b+%3\n" \
  51. ".previous\n"
  52. #else
  53. #define _EMIT_BUG_ENTRY \
  54. ".section __bug_table,\"aw\"\n" \
  55. "2: .4byte 1b - .\n" \
  56. " .short %2\n" \
  57. ".org 2b+%3\n" \
  58. ".previous\n"
  59. #endif
  60. #define BUG_ENTRY(insn, flags, ...) \
  61. __asm__ __volatile__( \
  62. "1: " insn "\n" \
  63. _EMIT_BUG_ENTRY \
  64. : : "i" (__FILE__), "i" (__LINE__), \
  65. "i" (flags), \
  66. "i" (sizeof(struct bug_entry)), \
  67. ##__VA_ARGS__)
  68. #define WARN_ENTRY(insn, flags, label, ...) \
  69. asm_volatile_goto( \
  70. "1: " insn "\n" \
  71. EX_TABLE(1b, %l[label]) \
  72. _EMIT_BUG_ENTRY \
  73. : : "i" (__FILE__), "i" (__LINE__), \
  74. "i" (flags), \
  75. "i" (sizeof(struct bug_entry)), \
  76. ##__VA_ARGS__ : : label)
  77. /*
  78. * BUG_ON() and WARN_ON() do their best to cooperate with compile-time
  79. * optimisations. However depending on the complexity of the condition
  80. * some compiler versions may not produce optimal results.
  81. */
  82. #define BUG() do { \
  83. BUG_ENTRY("twi 31, 0, 0", 0); \
  84. unreachable(); \
  85. } while (0)
  86. #define HAVE_ARCH_BUG
  87. #define __WARN_FLAGS(flags) do { \
  88. __label__ __label_warn_on; \
  89. \
  90. WARN_ENTRY("twi 31, 0, 0", BUGFLAG_WARNING | (flags), __label_warn_on); \
  91. unreachable(); \
  92. \
  93. __label_warn_on: \
  94. break; \
  95. } while (0)
  96. #ifdef CONFIG_PPC64
  97. #define BUG_ON(x) do { \
  98. if (__builtin_constant_p(x)) { \
  99. if (x) \
  100. BUG(); \
  101. } else { \
  102. BUG_ENTRY(PPC_TLNEI " %4, 0", 0, "r" ((__force long)(x))); \
  103. } \
  104. } while (0)
  105. #define WARN_ON(x) ({ \
  106. bool __ret_warn_on = false; \
  107. do { \
  108. if (__builtin_constant_p((x))) { \
  109. if (!(x)) \
  110. break; \
  111. __WARN(); \
  112. __ret_warn_on = true; \
  113. } else { \
  114. __label__ __label_warn_on; \
  115. \
  116. WARN_ENTRY(PPC_TLNEI " %4, 0", \
  117. BUGFLAG_WARNING | BUGFLAG_TAINT(TAINT_WARN), \
  118. __label_warn_on, \
  119. "r" ((__force long)(x))); \
  120. break; \
  121. __label_warn_on: \
  122. __ret_warn_on = true; \
  123. } \
  124. } while (0); \
  125. unlikely(__ret_warn_on); \
  126. })
  127. #define HAVE_ARCH_BUG_ON
  128. #define HAVE_ARCH_WARN_ON
  129. #endif
  130. #endif /* __ASSEMBLY __ */
  131. #else
  132. #ifdef __ASSEMBLY__
  133. .macro EMIT_BUG_ENTRY addr,file,line,flags
  134. .endm
  135. .macro EMIT_WARN_ENTRY addr,file,line,flags
  136. .endm
  137. #else /* !__ASSEMBLY__ */
  138. #define _EMIT_BUG_ENTRY
  139. #define _EMIT_WARN_ENTRY
  140. #endif
  141. #endif /* CONFIG_BUG */
  142. #include <asm-generic/bug.h>
  143. #ifndef __ASSEMBLY__
  144. struct pt_regs;
  145. void hash__do_page_fault(struct pt_regs *);
  146. void bad_page_fault(struct pt_regs *, int);
  147. extern void _exception(int, struct pt_regs *, int, unsigned long);
  148. extern void _exception_pkey(struct pt_regs *, unsigned long, int);
  149. extern void die(const char *, struct pt_regs *, long);
  150. void die_mce(const char *str, struct pt_regs *regs, long err);
  151. extern bool die_will_crash(void);
  152. extern void panic_flush_kmsg_start(void);
  153. extern void panic_flush_kmsg_end(void);
  154. #endif /* !__ASSEMBLY__ */
  155. #endif /* __KERNEL__ */
  156. #endif /* _ASM_POWERPC_BUG_H */