/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_S390_BUG_H #define _ASM_S390_BUG_H #include #include #define MONCODE_BUG _AC(0, U) #define MONCODE_BUG_ARG _AC(1, U) #ifndef __ASSEMBLER__ #if defined(CONFIG_BUG) && defined(CONFIG_CC_HAS_ASM_IMMEDIATE_STRINGS) #ifdef CONFIG_DEBUG_BUGVERBOSE #define __BUG_ENTRY_VERBOSE(format, file, line) \ " .long " format " - . # bug_entry::format\n" \ " .long " file " - . # bug_entry::file\n" \ " .short " line " # bug_entry::line\n" #else #define __BUG_ENTRY_VERBOSE(format, file, line) #endif #ifdef CONFIG_DEBUG_BUGVERBOSE_DETAILED #define WARN_CONDITION_STR(cond_str) cond_str #else #define WARN_CONDITION_STR(cond_str) "" #endif #define __BUG_ENTRY(format, file, line, flags, size) \ " .section __bug_table,\"aw\"\n" \ "1: .long 0b - . # bug_entry::bug_addr\n" \ __BUG_ENTRY_VERBOSE(format, file, line) \ " .short "flags" # bug_entry::flags\n" \ " .org 1b+"size"\n" \ " .previous" #define __BUG_ASM(cond_str, flags) \ do { \ asm_inline volatile("\n" \ "0: mc %[monc](%%r0),0\n" \ __BUG_ENTRY("%[frmt]", "%[file]", "%[line]", \ "%[flgs]", "%[size]") \ : \ : [monc] "i" (MONCODE_BUG), \ [frmt] "i" (WARN_CONDITION_STR(cond_str)), \ [file] "i" (__FILE__), \ [line] "i" (__LINE__), \ [flgs] "i" (flags), \ [size] "i" (sizeof(struct bug_entry))); \ } while (0) #define BUG() \ do { \ __BUG_ASM("", 0); \ unreachable(); \ } while (0) #define __WARN_FLAGS(cond_str, flags) \ do { \ __BUG_ASM(cond_str, BUGFLAG_WARNING | (flags)); \ } while (0) #define __WARN_bug_entry(flags, format) \ ({ \ struct bug_entry *bug; \ \ asm_inline volatile("\n" \ "0: larl %[bug],1f\n" \ __BUG_ENTRY("%[frmt]", "%[file]", "%[line]", \ "%[flgs]", "%[size]") \ : [bug] "=d" (bug) \ : [frmt] "i" (format), \ [file] "i" (__FILE__), \ [line] "i" (__LINE__), \ [flgs] "i" (flags), \ [size] "i" (sizeof(struct bug_entry))); \ bug; \ }) /* * Variable Argument List (va_list) as defined in ELF Application * Binary Interface s390x Supplement documentation. */ struct arch_va_list { long __gpr; long __fpr; void *__overflow_arg_area; void *__reg_save_area; }; struct bug_entry; struct pt_regs; void *__warn_args(struct arch_va_list *args, struct pt_regs *regs); void __WARN_trap(struct bug_entry *bug, ...); #define __WARN_print_arg(flags, format, arg...) \ do { \ int __flags = (flags) | BUGFLAG_WARNING | BUGFLAG_ARGS; \ \ __WARN_trap(__WARN_bug_entry(__flags, format), ## arg); \ /* prevent tail-call optimization */ \ asm(""); \ } while (0) #define __WARN_printf(taint, fmt, arg...) \ __WARN_print_arg(BUGFLAG_TAINT(taint), fmt, ## arg) #define WARN_ONCE(cond, format, arg...) \ ({ \ int __ret_warn_on = !!(cond); \ \ if (unlikely(__ret_warn_on)) { \ __WARN_print_arg(BUGFLAG_ONCE|BUGFLAG_TAINT(TAINT_WARN),\ format, ## arg); \ } \ __ret_warn_on; \ }) #define HAVE_ARCH_BUG #define HAVE_ARCH_BUG_FORMAT #define HAVE_ARCH_BUG_FORMAT_ARGS #endif /* CONFIG_BUG && CONFIG_CC_HAS_ASM_IMMEDIATE_STRINGS */ #endif /* __ASSEMBLER__ */ #include #endif /* _ASM_S390_BUG_H */