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