xref: /linux/arch/s390/include/asm/bug.h (revision d639d9fa162aadec1ae9980c4dcf6e50bd2f8290)
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