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