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