Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/include/asm-generic/bug.h
26278 views
1
/* SPDX-License-Identifier: GPL-2.0 */
2
#ifndef _ASM_GENERIC_BUG_H
3
#define _ASM_GENERIC_BUG_H
4
5
#include <linux/compiler.h>
6
#include <linux/instrumentation.h>
7
#include <linux/once_lite.h>
8
9
#define CUT_HERE "------------[ cut here ]------------\n"
10
11
#ifdef CONFIG_GENERIC_BUG
12
#define BUGFLAG_WARNING (1 << 0)
13
#define BUGFLAG_ONCE (1 << 1)
14
#define BUGFLAG_DONE (1 << 2)
15
#define BUGFLAG_NO_CUT_HERE (1 << 3) /* CUT_HERE already sent */
16
#define BUGFLAG_TAINT(taint) ((taint) << 8)
17
#define BUG_GET_TAINT(bug) ((bug)->flags >> 8)
18
#endif
19
20
#ifndef __ASSEMBLY__
21
#include <linux/panic.h>
22
#include <linux/printk.h>
23
24
struct warn_args;
25
struct pt_regs;
26
27
void __warn(const char *file, int line, void *caller, unsigned taint,
28
struct pt_regs *regs, struct warn_args *args);
29
30
#ifdef CONFIG_BUG
31
32
#ifdef CONFIG_GENERIC_BUG
33
struct bug_entry {
34
#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
35
unsigned long bug_addr;
36
#else
37
signed int bug_addr_disp;
38
#endif
39
#ifdef CONFIG_DEBUG_BUGVERBOSE
40
#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
41
const char *file;
42
#else
43
signed int file_disp;
44
#endif
45
unsigned short line;
46
#endif
47
unsigned short flags;
48
};
49
#endif /* CONFIG_GENERIC_BUG */
50
51
/*
52
* Don't use BUG() or BUG_ON() unless there's really no way out; one
53
* example might be detecting data structure corruption in the middle
54
* of an operation that can't be backed out of. If the (sub)system
55
* can somehow continue operating, perhaps with reduced functionality,
56
* it's probably not BUG-worthy.
57
*
58
* If you're tempted to BUG(), think again: is completely giving up
59
* really the *only* solution? There are usually better options, where
60
* users don't need to reboot ASAP and can mostly shut down cleanly.
61
*/
62
#ifndef HAVE_ARCH_BUG
63
#define BUG() do { \
64
printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
65
barrier_before_unreachable(); \
66
panic("BUG!"); \
67
} while (0)
68
#endif
69
70
#ifndef HAVE_ARCH_BUG_ON
71
#define BUG_ON(condition) do { if (unlikely(condition)) BUG(); } while (0)
72
#endif
73
74
/*
75
* WARN(), WARN_ON(), WARN_ON_ONCE(), and so on can be used to report
76
* significant kernel issues that need prompt attention if they should ever
77
* appear at runtime.
78
*
79
* Do not use these macros when checking for invalid external inputs
80
* (e.g. invalid system call arguments, or invalid data coming from
81
* network/devices), and on transient conditions like ENOMEM or EAGAIN.
82
* These macros should be used for recoverable kernel issues only.
83
* For invalid external inputs, transient conditions, etc use
84
* pr_err[_once/_ratelimited]() followed by dump_stack(), if necessary.
85
* Do not include "BUG"/"WARNING" in format strings manually to make these
86
* conditions distinguishable from kernel issues.
87
*
88
* Use the versions with printk format strings to provide better diagnostics.
89
*/
90
extern __printf(4, 5)
91
void warn_slowpath_fmt(const char *file, const int line, unsigned taint,
92
const char *fmt, ...);
93
extern __printf(1, 2) void __warn_printk(const char *fmt, ...);
94
95
#ifndef __WARN_FLAGS
96
#define __WARN() __WARN_printf(TAINT_WARN, NULL)
97
#define __WARN_printf(taint, arg...) do { \
98
instrumentation_begin(); \
99
warn_slowpath_fmt(__FILE__, __LINE__, taint, arg); \
100
instrumentation_end(); \
101
} while (0)
102
#else
103
#define __WARN() __WARN_FLAGS(BUGFLAG_TAINT(TAINT_WARN))
104
#define __WARN_printf(taint, arg...) do { \
105
instrumentation_begin(); \
106
__warn_printk(arg); \
107
__WARN_FLAGS(BUGFLAG_NO_CUT_HERE | BUGFLAG_TAINT(taint));\
108
instrumentation_end(); \
109
} while (0)
110
#define WARN_ON_ONCE(condition) ({ \
111
int __ret_warn_on = !!(condition); \
112
if (unlikely(__ret_warn_on)) \
113
__WARN_FLAGS(BUGFLAG_ONCE | \
114
BUGFLAG_TAINT(TAINT_WARN)); \
115
unlikely(__ret_warn_on); \
116
})
117
#endif
118
119
/* used internally by panic.c */
120
121
#ifndef WARN_ON
122
#define WARN_ON(condition) ({ \
123
int __ret_warn_on = !!(condition); \
124
if (unlikely(__ret_warn_on)) \
125
__WARN(); \
126
unlikely(__ret_warn_on); \
127
})
128
#endif
129
130
#ifndef WARN
131
#define WARN(condition, format...) ({ \
132
int __ret_warn_on = !!(condition); \
133
if (unlikely(__ret_warn_on)) \
134
__WARN_printf(TAINT_WARN, format); \
135
unlikely(__ret_warn_on); \
136
})
137
#endif
138
139
#define WARN_TAINT(condition, taint, format...) ({ \
140
int __ret_warn_on = !!(condition); \
141
if (unlikely(__ret_warn_on)) \
142
__WARN_printf(taint, format); \
143
unlikely(__ret_warn_on); \
144
})
145
146
#ifndef WARN_ON_ONCE
147
#define WARN_ON_ONCE(condition) \
148
DO_ONCE_LITE_IF(condition, WARN_ON, 1)
149
#endif
150
151
#define WARN_ONCE(condition, format...) \
152
DO_ONCE_LITE_IF(condition, WARN, 1, format)
153
154
#define WARN_TAINT_ONCE(condition, taint, format...) \
155
DO_ONCE_LITE_IF(condition, WARN_TAINT, 1, taint, format)
156
157
#else /* !CONFIG_BUG */
158
#ifndef HAVE_ARCH_BUG
159
#define BUG() do { \
160
do {} while (1); \
161
unreachable(); \
162
} while (0)
163
#endif
164
165
#ifndef HAVE_ARCH_BUG_ON
166
#define BUG_ON(condition) do { if (unlikely(condition)) BUG(); } while (0)
167
#endif
168
169
#ifndef HAVE_ARCH_WARN_ON
170
#define WARN_ON(condition) ({ \
171
int __ret_warn_on = !!(condition); \
172
unlikely(__ret_warn_on); \
173
})
174
#endif
175
176
#ifndef WARN
177
#define WARN(condition, format...) ({ \
178
int __ret_warn_on = !!(condition); \
179
no_printk(format); \
180
unlikely(__ret_warn_on); \
181
})
182
#endif
183
184
#define WARN_ON_ONCE(condition) WARN_ON(condition)
185
#define WARN_ONCE(condition, format...) WARN(condition, format)
186
#define WARN_TAINT(condition, taint, format...) WARN(condition, format)
187
#define WARN_TAINT_ONCE(condition, taint, format...) WARN(condition, format)
188
189
#endif
190
191
/*
192
* WARN_ON_SMP() is for cases that the warning is either
193
* meaningless for !SMP or may even cause failures.
194
* It can also be used with values that are only defined
195
* on SMP:
196
*
197
* struct foo {
198
* [...]
199
* #ifdef CONFIG_SMP
200
* int bar;
201
* #endif
202
* };
203
*
204
* void func(struct foo *zoot)
205
* {
206
* WARN_ON_SMP(!zoot->bar);
207
*
208
* For CONFIG_SMP, WARN_ON_SMP() should act the same as WARN_ON(),
209
* and should be a nop and return false for uniprocessor.
210
*
211
* if (WARN_ON_SMP(x)) returns true only when CONFIG_SMP is set
212
* and x is true.
213
*/
214
#ifdef CONFIG_SMP
215
# define WARN_ON_SMP(x) WARN_ON(x)
216
#else
217
/*
218
* Use of ({0;}) because WARN_ON_SMP(x) may be used either as
219
* a stand alone line statement or as a condition in an if ()
220
* statement.
221
* A simple "0" would cause gcc to give a "statement has no effect"
222
* warning.
223
*/
224
# define WARN_ON_SMP(x) ({0;})
225
#endif
226
227
#endif /* __ASSEMBLY__ */
228
229
#endif
230
231