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