|
2 | 2 | #ifndef _ASM_S390_BUG_H |
3 | 3 | #define _ASM_S390_BUG_H |
4 | 4 |
|
5 | | -#include <linux/stringify.h> |
| 5 | +#include <linux/compiler.h> |
| 6 | +#include <linux/const.h> |
6 | 7 |
|
7 | | -#ifdef CONFIG_BUG |
| 8 | +#define MONCODE_BUG _AC(0, U) |
| 9 | +#define MONCODE_BUG_ARG _AC(1, U) |
8 | 10 |
|
9 | | -#ifndef CONFIG_DEBUG_BUGVERBOSE |
10 | | -#define _BUGVERBOSE_LOCATION(file, line) |
| 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" |
11 | 19 | #else |
12 | | -#define __BUGVERBOSE_LOCATION(file, line) \ |
13 | | - .pushsection .rodata.str, "aMS", @progbits, 1; \ |
14 | | - .align 2; \ |
15 | | - 10002: .ascii file "\0"; \ |
16 | | - .popsection; \ |
17 | | - \ |
18 | | - .long 10002b - .; \ |
19 | | - .short line; |
20 | | -#define _BUGVERBOSE_LOCATION(file, line) __BUGVERBOSE_LOCATION(file, line) |
| 20 | +#define __BUG_ENTRY_VERBOSE(format, file, line) |
21 | 21 | #endif |
22 | 22 |
|
23 | | -#ifndef CONFIG_GENERIC_BUG |
24 | | -#define __BUG_ENTRY(cond_str, flags) |
| 23 | +#ifdef CONFIG_DEBUG_BUGVERBOSE_DETAILED |
| 24 | +#define WARN_CONDITION_STR(cond_str) cond_str |
25 | 25 | #else |
26 | | -#define __BUG_ENTRY(cond_str, flags) \ |
27 | | - .pushsection __bug_table, "aw"; \ |
28 | | - .align 4; \ |
29 | | - 10000: .long 10001f - .; \ |
30 | | - _BUGVERBOSE_LOCATION(WARN_CONDITION_STR(cond_str) __FILE__, __LINE__) \ |
31 | | - .short flags; \ |
32 | | - .popsection; \ |
33 | | - 10001: |
| 26 | +#define WARN_CONDITION_STR(cond_str) "" |
34 | 27 | #endif |
35 | 28 |
|
36 | | -#define ASM_BUG_FLAGS(cond_str, flags) \ |
37 | | - __BUG_ENTRY(cond_str, flags) \ |
38 | | - mc 0,0 |
| 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" |
39 | 36 |
|
40 | | -#define ASM_BUG() ASM_BUG_FLAGS("", 0) |
| 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) |
41 | 51 |
|
42 | | -#define __BUG_FLAGS(cond_str, flags) \ |
43 | | - asm_inline volatile(__stringify(ASM_BUG_FLAGS(cond_str, flags))); |
| 52 | +#define BUG() \ |
| 53 | +do { \ |
| 54 | + __BUG_ASM("", 0); \ |
| 55 | + unreachable(); \ |
| 56 | +} while (0) |
44 | 57 |
|
45 | | -#define __WARN_FLAGS(cond_str, flags) \ |
46 | | -do { \ |
47 | | - __BUG_FLAGS(cond_str, BUGFLAG_WARNING|(flags)); \ |
| 58 | +#define __WARN_FLAGS(cond_str, flags) \ |
| 59 | +do { \ |
| 60 | + __BUG_ASM(cond_str, BUGFLAG_WARNING | (flags)); \ |
48 | 61 | } while (0) |
49 | 62 |
|
50 | | -#define BUG() \ |
51 | | -do { \ |
52 | | - __BUG_FLAGS("", 0); \ |
53 | | - unreachable(); \ |
| 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(""); \ |
54 | 104 | } while (0) |
55 | 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 | + |
56 | 120 | #define HAVE_ARCH_BUG |
| 121 | +#define HAVE_ARCH_BUG_FORMAT |
| 122 | +#define HAVE_ARCH_BUG_FORMAT_ARGS |
57 | 123 |
|
58 | | -#endif /* CONFIG_BUG */ |
| 124 | +#endif /* CONFIG_BUG && CONFIG_CC_HAS_ASM_IMMEDIATE_STRINGS */ |
| 125 | +#endif /* __ASSEMBLER__ */ |
59 | 126 |
|
60 | 127 | #include <asm-generic/bug.h> |
61 | 128 |
|
|
0 commit comments