1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _ASM_S390_BUG_H 3 #define _ASM_S390_BUG_H 4 5 #include <linux/compiler.h> 6 #include <linux/const.h> 7 8 #define MONCODE_BUG _AC(0, U) 9 #define MONCODE_BUG_ARG _AC(1, U) 10 11 #ifndef __ASSEMBLER__ 12 #if defined(CONFIG_BUG) && defined(CONFIG_CC_HAS_ASM_IMMEDIATE_STRINGS) 13 14 #ifdef CONFIG_DEBUG_BUGVERBOSE 15 #define __BUG_ENTRY_VERBOSE(format, file, line) \ 16 " .long " format " - . # bug_entry::format\n" \ 17 " .long " file " - . # bug_entry::file\n" \ 18 " .short " line " # bug_entry::line\n" 19 #else 20 #define __BUG_ENTRY_VERBOSE(format, file, line) 21 #endif 22 23 #ifdef CONFIG_DEBUG_BUGVERBOSE_DETAILED 24 #define WARN_CONDITION_STR(cond_str) cond_str 25 #else 26 #define WARN_CONDITION_STR(cond_str) "" 27 #endif 28 29 #define __BUG_ENTRY(format, file, line, flags, size) \ 30 " .section __bug_table,\"aw\"\n" \ 31 "1: .long 0b - . # bug_entry::bug_addr\n" \ 32 __BUG_ENTRY_VERBOSE(format, file, line) \ 33 " .short "flags" # bug_entry::flags\n" \ 34 " .org 1b+"size"\n" \ 35 " .previous" 36 37 #define __BUG_ASM(cond_str, flags) \ 38 do { \ 39 asm_inline volatile("\n" \ 40 "0: mc %[monc](%%r0),0\n" \ 41 __BUG_ENTRY("%[frmt]", "%[file]", "%[line]", \ 42 "%[flgs]", "%[size]") \ 43 : \ 44 : [monc] "i" (MONCODE_BUG), \ 45 [frmt] "i" (WARN_CONDITION_STR(cond_str)), \ 46 [file] "i" (__FILE__), \ 47 [line] "i" (__LINE__), \ 48 [flgs] "i" (flags), \ 49 [size] "i" (sizeof(struct bug_entry))); \ 50 } while (0) 51 52 #define BUG() \ 53 do { \ 54 __BUG_ASM("", 0); \ 55 unreachable(); \ 56 } while (0) 57 58 #define __WARN_FLAGS(cond_str, flags) \ 59 do { \ 60 __BUG_ASM(cond_str, BUGFLAG_WARNING | (flags)); \ 61 } while (0) 62 63 #define __WARN_bug_entry(flags, format) \ 64 ({ \ 65 struct bug_entry *bug; \ 66 \ 67 asm_inline volatile("\n" \ 68 "0: larl %[bug],1f\n" \ 69 __BUG_ENTRY("%[frmt]", "%[file]", "%[line]", \ 70 "%[flgs]", "%[size]") \ 71 : [bug] "=d" (bug) \ 72 : [frmt] "i" (format), \ 73 [file] "i" (__FILE__), \ 74 [line] "i" (__LINE__), \ 75 [flgs] "i" (flags), \ 76 [size] "i" (sizeof(struct bug_entry))); \ 77 bug; \ 78 }) 79 80 /* 81 * Variable Argument List (va_list) as defined in ELF Application 82 * Binary Interface s390x Supplement documentation. 83 */ 84 struct arch_va_list { 85 long __gpr; 86 long __fpr; 87 void *__overflow_arg_area; 88 void *__reg_save_area; 89 }; 90 91 struct bug_entry; 92 struct pt_regs; 93 94 void *__warn_args(struct arch_va_list *args, struct pt_regs *regs); 95 void __WARN_trap(struct bug_entry *bug, ...); 96 97 #define __WARN_print_arg(flags, format, arg...) \ 98 do { \ 99 int __flags = (flags) | BUGFLAG_WARNING | BUGFLAG_ARGS; \ 100 \ 101 __WARN_trap(__WARN_bug_entry(__flags, format), ## arg); \ 102 /* prevent tail-call optimization */ \ 103 asm(""); \ 104 } while (0) 105 106 #define __WARN_printf(taint, fmt, arg...) \ 107 __WARN_print_arg(BUGFLAG_TAINT(taint), fmt, ## arg) 108 109 #define WARN_ONCE(cond, format, arg...) \ 110 ({ \ 111 int __ret_warn_on = !!(cond); \ 112 \ 113 if (unlikely(__ret_warn_on)) { \ 114 __WARN_print_arg(BUGFLAG_ONCE|BUGFLAG_TAINT(TAINT_WARN),\ 115 format, ## arg); \ 116 } \ 117 __ret_warn_on; \ 118 }) 119 120 #define HAVE_ARCH_BUG 121 #define HAVE_ARCH_BUG_FORMAT 122 #define HAVE_ARCH_BUG_FORMAT_ARGS 123 124 #endif /* CONFIG_BUG && CONFIG_CC_HAS_ASM_IMMEDIATE_STRINGS */ 125 #endif /* __ASSEMBLER__ */ 126 127 #include <asm-generic/bug.h> 128 129 #endif /* _ASM_S390_BUG_H */ 130