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() do { \
 108        printk(KERN_WARNING CUT_HERE); __WARN_TAINT(TAINT_WARN); \
 109} while (0)
 110#define __WARN_printf(arg...)   __WARN_printf_taint(TAINT_WARN, arg)
 111#define __WARN_printf_taint(taint, arg...)                              \
 112        do { __warn_printk(arg); __WARN_TAINT(taint); } while (0)
 113#endif
 114
 115/* used internally by panic.c */
 116struct warn_args;
 117struct pt_regs;
 118
 119void __warn(const char *file, int line, void *caller, unsigned taint,
 120            struct pt_regs *regs, struct warn_args *args);
 121
 122#ifndef WARN_ON
 123#define WARN_ON(condition) ({                                           \
 124        int __ret_warn_on = !!(condition);                              \
 125        if (unlikely(__ret_warn_on))                                    \
 126                __WARN();                                               \
 127        unlikely(__ret_warn_on);                                        \
 128})
 129#endif
 130
 131#ifndef WARN
 132#define WARN(condition, format...) ({                                   \
 133        int __ret_warn_on = !!(condition);                              \
 134        if (unlikely(__ret_warn_on))                                    \
 135                __WARN_printf(format);                                  \
 136        unlikely(__ret_warn_on);                                        \
 137})
 138#endif
 139
 140#define WARN_TAINT(condition, taint, format...) ({                      \
 141        int __ret_warn_on = !!(condition);                              \
 142        if (unlikely(__ret_warn_on))                                    \
 143                __WARN_printf_taint(taint, format);                     \
 144        unlikely(__ret_warn_on);                                        \
 145})
 146
 147#ifndef WARN_ON_ONCE
 148#define WARN_ON_ONCE(condition) ({                              \
 149        static bool __section(.data.once) __warned;             \
 150        int __ret_warn_once = !!(condition);                    \
 151                                                                \
 152        if (unlikely(__ret_warn_once && !__warned)) {           \
 153                __warned = true;                                \
 154                WARN_ON(1);                                     \
 155        }                                                       \
 156        unlikely(__ret_warn_once);                              \
 157})
 158#endif
 159
 160#define WARN_ONCE(condition, 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(1, format);                                \
 167        }                                                       \
 168        unlikely(__ret_warn_once);                              \
 169})
 170
 171#define WARN_TAINT_ONCE(condition, taint, format...)    ({      \
 172        static bool __section(.data.once) __warned;             \
 173        int __ret_warn_once = !!(condition);                    \
 174                                                                \
 175        if (unlikely(__ret_warn_once && !__warned)) {           \
 176                __warned = true;                                \
 177                WARN_TAINT(1, taint, format);                   \
 178        }                                                       \
 179        unlikely(__ret_warn_once);                              \
 180})
 181
 182#else /* !CONFIG_BUG */
 183#ifndef HAVE_ARCH_BUG
 184#define BUG() do {} while (1)
 185#endif
 186
 187#ifndef HAVE_ARCH_BUG_ON
 188#define BUG_ON(condition) do { if (condition) BUG(); } while (0)
 189#endif
 190
 191#ifndef HAVE_ARCH_WARN_ON
 192#define WARN_ON(condition) ({                                           \
 193        int __ret_warn_on = !!(condition);                              \
 194        unlikely(__ret_warn_on);                                        \
 195})
 196#endif
 197
 198#ifndef WARN
 199#define WARN(condition, format...) ({                                   \
 200        int __ret_warn_on = !!(condition);                              \
 201        no_printk(format);                                              \
 202        unlikely(__ret_warn_on);                                        \
 203})
 204#endif
 205
 206#define WARN_ON_ONCE(condition) WARN_ON(condition)
 207#define WARN_ONCE(condition, format...) WARN(condition, format)
 208#define WARN_TAINT(condition, taint, format...) WARN(condition, format)
 209#define WARN_TAINT_ONCE(condition, taint, format...) WARN(condition, format)
 210
 211#endif
 212
 213/*
 214 * WARN_ON_SMP() is for cases that the warning is either
 215 * meaningless for !SMP or may even cause failures.
 216 * It can also be used with values that are only defined
 217 * on SMP:
 218 *
 219 * struct foo {
 220 *  [...]
 221 * #ifdef CONFIG_SMP
 222 *      int bar;
 223 * #endif
 224 * };
 225 *
 226 * void func(struct foo *zoot)
 227 * {
 228 *      WARN_ON_SMP(!zoot->bar);
 229 *
 230 * For CONFIG_SMP, WARN_ON_SMP() should act the same as WARN_ON(),
 231 * and should be a nop and return false for uniprocessor.
 232 *
 233 * if (WARN_ON_SMP(x)) returns true only when CONFIG_SMP is set
 234 * and x is true.
 235 */
 236#ifdef CONFIG_SMP
 237# define WARN_ON_SMP(x)                 WARN_ON(x)
 238#else
 239/*
 240 * Use of ({0;}) because WARN_ON_SMP(x) may be used either as
 241 * a stand alone line statement or as a condition in an if ()
 242 * statement.
 243 * A simple "0" would cause gcc to give a "statement has no effect"
 244 * warning.
 245 */
 246# define WARN_ON_SMP(x)                 ({0;})
 247#endif
 248
 249#endif /* __ASSEMBLY__ */
 250
 251#endif
 252