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