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