b24413180f560 (Greg Kroah-Hartman 2017-11-01 15:07:57 +0100 1) // SPDX-License-Identifier: GPL-2.0
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 2) /*
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 3) Generic support for BUG()
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 4)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 5) This respects the following config options:
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 6)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 7) CONFIG_BUG - emit BUG traps. Nothing happens without this.
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 8) CONFIG_GENERIC_BUG - enable this code.
b93a531e315e9 (Jan Beulich 2008-12-16 11:40:27 +0000 9) CONFIG_GENERIC_BUG_RELATIVE_POINTERS - use 32-bit pointers relative to
b93a531e315e9 (Jan Beulich 2008-12-16 11:40:27 +0000 10) the containing struct bug_entry for bug_addr and file.
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 11) CONFIG_DEBUG_BUGVERBOSE - emit full file+line information for each BUG
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 12)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 13) CONFIG_BUG and CONFIG_DEBUG_BUGVERBOSE are potentially user-settable
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 14) (though they're generally always on).
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 15)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 16) CONFIG_GENERIC_BUG is set by each architecture using this code.
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 17)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 18) To use this, your architecture must:
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 19)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 20) 1. Set up the config options:
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 21) - Enable CONFIG_GENERIC_BUG if CONFIG_BUG
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 22)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 23) 2. Implement BUG (and optionally BUG_ON, WARN, WARN_ON)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 24) - Define HAVE_ARCH_BUG
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 25) - Implement BUG() to generate a faulting instruction
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 26) - NOTE: struct bug_entry does not have "file" or "line" entries
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 27) when CONFIG_DEBUG_BUGVERBOSE is not enabled, so you must generate
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 28) the values accordingly.
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 29)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 30) 3. Implement the trap
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 31) - In the illegal instruction trap handler (typically), verify
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 32) that the fault was in kernel mode, and call report_bug()
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 33) - report_bug() will return whether it was a false alarm, a warning,
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 34) or an actual bug.
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 35) - You must implement the is_valid_bugaddr(bugaddr) callback which
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 36) returns true if the eip is a real kernel address, and it points
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 37) to the expected BUG trap instruction.
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 38)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 39) Jeremy Fitzhardinge <jeremy@goop.org> 2006
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 40) */
c56ba70331d9f (Fabian Frederick 2014-06-04 16:11:59 -0700 41)
c56ba70331d9f (Fabian Frederick 2014-06-04 16:11:59 -0700 42) #define pr_fmt(fmt) fmt
c56ba70331d9f (Fabian Frederick 2014-06-04 16:11:59 -0700 43)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 44) #include <linux/list.h>
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 45) #include <linux/module.h>
da9eac8990dc6 (Paul Mundt 2008-07-04 09:59:36 -0700 46) #include <linux/kernel.h>
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 47) #include <linux/bug.h>
608e2619682e9 (Heiko Carstens 2007-07-15 23:41:39 -0700 48) #include <linux/sched.h>
b2d091031075a (Ingo Molnar 2017-02-04 01:27:20 +0100 49) #include <linux/rculist.h>
58f6e384480ec (Peter Zijlstra 2020-05-28 16:52:40 +0200 50) #include <linux/ftrace.h>
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 51)
19d436268dde9 (Peter Zijlstra 2017-02-25 08:56:53 +0100 52) extern struct bug_entry __start___bug_table[], __stop___bug_table[];
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 53)
b93a531e315e9 (Jan Beulich 2008-12-16 11:40:27 +0000 54) static inline unsigned long bug_addr(const struct bug_entry *bug)
b93a531e315e9 (Jan Beulich 2008-12-16 11:40:27 +0000 55) {
b93a531e315e9 (Jan Beulich 2008-12-16 11:40:27 +0000 56) #ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
b93a531e315e9 (Jan Beulich 2008-12-16 11:40:27 +0000 57) return bug->bug_addr;
b93a531e315e9 (Jan Beulich 2008-12-16 11:40:27 +0000 58) #else
b93a531e315e9 (Jan Beulich 2008-12-16 11:40:27 +0000 59) return (unsigned long)bug + bug->bug_addr_disp;
b93a531e315e9 (Jan Beulich 2008-12-16 11:40:27 +0000 60) #endif
b93a531e315e9 (Jan Beulich 2008-12-16 11:40:27 +0000 61) }
b93a531e315e9 (Jan Beulich 2008-12-16 11:40:27 +0000 62)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 63) #ifdef CONFIG_MODULES
1fb9341ac3482 (Rusty Russell 2013-01-12 13:27:34 +1030 64) /* Updates are protected by module mutex */
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 65) static LIST_HEAD(module_bug_list);
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 66)
19d436268dde9 (Peter Zijlstra 2017-02-25 08:56:53 +0100 67) static struct bug_entry *module_find_bug(unsigned long bugaddr)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 68) {
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 69) struct module *mod;
19d436268dde9 (Peter Zijlstra 2017-02-25 08:56:53 +0100 70) struct bug_entry *bug = NULL;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 71)
0be964be0d450 (Peter Zijlstra 2015-05-27 11:09:35 +0930 72) rcu_read_lock_sched();
0286b5ea125e5 (Masami Hiramatsu 2014-11-10 09:28:29 +1030 73) list_for_each_entry_rcu(mod, &module_bug_list, bug_list) {
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 74) unsigned i;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 75)
0286b5ea125e5 (Masami Hiramatsu 2014-11-10 09:28:29 +1030 76) bug = mod->bug_table;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 77) for (i = 0; i < mod->num_bugs; ++i, ++bug)
b93a531e315e9 (Jan Beulich 2008-12-16 11:40:27 +0000 78) if (bugaddr == bug_addr(bug))
0286b5ea125e5 (Masami Hiramatsu 2014-11-10 09:28:29 +1030 79) goto out;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 80) }
0286b5ea125e5 (Masami Hiramatsu 2014-11-10 09:28:29 +1030 81) bug = NULL;
0286b5ea125e5 (Masami Hiramatsu 2014-11-10 09:28:29 +1030 82) out:
0be964be0d450 (Peter Zijlstra 2015-05-27 11:09:35 +0930 83) rcu_read_unlock_sched();
0286b5ea125e5 (Masami Hiramatsu 2014-11-10 09:28:29 +1030 84)
0286b5ea125e5 (Masami Hiramatsu 2014-11-10 09:28:29 +1030 85) return bug;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 86) }
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 87)
5336377d62259 (Linus Torvalds 2010-10-05 11:29:27 -0700 88) void module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
5336377d62259 (Linus Torvalds 2010-10-05 11:29:27 -0700 89) struct module *mod)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 90) {
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 91) char *secstrings;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 92) unsigned int i;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 93)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 94) mod->bug_table = NULL;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 95) mod->num_bugs = 0;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 96)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 97) /* Find the __bug_table section, if present */
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 98) secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 99) for (i = 1; i < hdr->e_shnum; i++) {
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 100) if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table"))
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 101) continue;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 102) mod->bug_table = (void *) sechdrs[i].sh_addr;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 103) mod->num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry);
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 104) break;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 105) }
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 106)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 107) /*
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 108) * Strictly speaking this should have a spinlock to protect against
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 109) * traversals, but since we only traverse on BUG()s, a spinlock
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 110) * could potentially lead to deadlock and thus be counter-productive.
0286b5ea125e5 (Masami Hiramatsu 2014-11-10 09:28:29 +1030 111) * Thus, this uses RCU to safely manipulate the bug list, since BUG
0286b5ea125e5 (Masami Hiramatsu 2014-11-10 09:28:29 +1030 112) * must run in non-interruptive state.
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 113) */
0286b5ea125e5 (Masami Hiramatsu 2014-11-10 09:28:29 +1030 114) list_add_rcu(&mod->bug_list, &module_bug_list);
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 115) }
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 116)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 117) void module_bug_cleanup(struct module *mod)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 118) {
0286b5ea125e5 (Masami Hiramatsu 2014-11-10 09:28:29 +1030 119) list_del_rcu(&mod->bug_list);
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 120) }
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 121)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 122) #else
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 123)
19d436268dde9 (Peter Zijlstra 2017-02-25 08:56:53 +0100 124) static inline struct bug_entry *module_find_bug(unsigned long bugaddr)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 125) {
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 126) return NULL;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 127) }
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 128) #endif
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 129)
26dbc7e299c7e (Andrew Scull 2021-03-18 14:33:08 +0000 130) void bug_get_file_line(struct bug_entry *bug, const char **file,
26dbc7e299c7e (Andrew Scull 2021-03-18 14:33:08 +0000 131) unsigned int *line)
26dbc7e299c7e (Andrew Scull 2021-03-18 14:33:08 +0000 132) {
26dbc7e299c7e (Andrew Scull 2021-03-18 14:33:08 +0000 133) #ifdef CONFIG_DEBUG_BUGVERBOSE
26dbc7e299c7e (Andrew Scull 2021-03-18 14:33:08 +0000 134) #ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
26dbc7e299c7e (Andrew Scull 2021-03-18 14:33:08 +0000 135) *file = bug->file;
26dbc7e299c7e (Andrew Scull 2021-03-18 14:33:08 +0000 136) #else
26dbc7e299c7e (Andrew Scull 2021-03-18 14:33:08 +0000 137) *file = (const char *)bug + bug->file_disp;
26dbc7e299c7e (Andrew Scull 2021-03-18 14:33:08 +0000 138) #endif
26dbc7e299c7e (Andrew Scull 2021-03-18 14:33:08 +0000 139) *line = bug->line;
5b8be5d875a99 (Andrew Scull 2021-03-18 14:33:09 +0000 140) #else
5b8be5d875a99 (Andrew Scull 2021-03-18 14:33:09 +0000 141) *file = NULL;
5b8be5d875a99 (Andrew Scull 2021-03-18 14:33:09 +0000 142) *line = 0;
26dbc7e299c7e (Andrew Scull 2021-03-18 14:33:08 +0000 143) #endif
26dbc7e299c7e (Andrew Scull 2021-03-18 14:33:08 +0000 144) }
26dbc7e299c7e (Andrew Scull 2021-03-18 14:33:08 +0000 145)
19d436268dde9 (Peter Zijlstra 2017-02-25 08:56:53 +0100 146) struct bug_entry *find_bug(unsigned long bugaddr)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 147) {
19d436268dde9 (Peter Zijlstra 2017-02-25 08:56:53 +0100 148) struct bug_entry *bug;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 149)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 150) for (bug = __start___bug_table; bug < __stop___bug_table; ++bug)
b93a531e315e9 (Jan Beulich 2008-12-16 11:40:27 +0000 151) if (bugaddr == bug_addr(bug))
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 152) return bug;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 153)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 154) return module_find_bug(bugaddr);
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 155) }
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 156)
608e2619682e9 (Heiko Carstens 2007-07-15 23:41:39 -0700 157) enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 158) {
19d436268dde9 (Peter Zijlstra 2017-02-25 08:56:53 +0100 159) struct bug_entry *bug;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 160) const char *file;
19d436268dde9 (Peter Zijlstra 2017-02-25 08:56:53 +0100 161) unsigned line, warning, once, done;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 162)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 163) if (!is_valid_bugaddr(bugaddr))
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 164) return BUG_TRAP_TYPE_NONE;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 165)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 166) bug = find_bug(bugaddr);
1b4cfe3c0a30d (Kees Cook 2018-03-09 15:51:02 -0800 167) if (!bug)
1b4cfe3c0a30d (Kees Cook 2018-03-09 15:51:02 -0800 168) return BUG_TRAP_TYPE_NONE;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 169)
58f6e384480ec (Peter Zijlstra 2020-05-28 16:52:40 +0200 170) disable_trace_on_warning();
58f6e384480ec (Peter Zijlstra 2020-05-28 16:52:40 +0200 171)
26dbc7e299c7e (Andrew Scull 2021-03-18 14:33:08 +0000 172) bug_get_file_line(bug, &file, &line);
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 173)
3ad1a6cb0abc6 (Andrew Scull 2021-03-18 14:33:07 +0000 174) warning = (bug->flags & BUGFLAG_WARNING) != 0;
3ad1a6cb0abc6 (Andrew Scull 2021-03-18 14:33:07 +0000 175) once = (bug->flags & BUGFLAG_ONCE) != 0;
3ad1a6cb0abc6 (Andrew Scull 2021-03-18 14:33:07 +0000 176) done = (bug->flags & BUGFLAG_DONE) != 0;
3ad1a6cb0abc6 (Andrew Scull 2021-03-18 14:33:07 +0000 177)
3ad1a6cb0abc6 (Andrew Scull 2021-03-18 14:33:07 +0000 178) if (warning && once) {
3ad1a6cb0abc6 (Andrew Scull 2021-03-18 14:33:07 +0000 179) if (done)
3ad1a6cb0abc6 (Andrew Scull 2021-03-18 14:33:07 +0000 180) return BUG_TRAP_TYPE_WARN;
3ad1a6cb0abc6 (Andrew Scull 2021-03-18 14:33:07 +0000 181)
3ad1a6cb0abc6 (Andrew Scull 2021-03-18 14:33:07 +0000 182) /*
3ad1a6cb0abc6 (Andrew Scull 2021-03-18 14:33:07 +0000 183) * Since this is the only store, concurrency is not an issue.
3ad1a6cb0abc6 (Andrew Scull 2021-03-18 14:33:07 +0000 184) */
3ad1a6cb0abc6 (Andrew Scull 2021-03-18 14:33:07 +0000 185) bug->flags |= BUGFLAG_DONE;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 186) }
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 187)
a44f71a9ab99b (Kees Cook 2019-09-25 16:48:11 -0700 188) /*
a44f71a9ab99b (Kees Cook 2019-09-25 16:48:11 -0700 189) * BUG() and WARN_ON() families don't print a custom debug message
a44f71a9ab99b (Kees Cook 2019-09-25 16:48:11 -0700 190) * before triggering the exception handler, so we must add the
a44f71a9ab99b (Kees Cook 2019-09-25 16:48:11 -0700 191) * "cut here" line now. WARN() issues its own "cut here" before the
a44f71a9ab99b (Kees Cook 2019-09-25 16:48:11 -0700 192) * extra debugging message it writes before triggering the handler.
a44f71a9ab99b (Kees Cook 2019-09-25 16:48:11 -0700 193) */
a44f71a9ab99b (Kees Cook 2019-09-25 16:48:11 -0700 194) if ((bug->flags & BUGFLAG_NO_CUT_HERE) == 0)
a44f71a9ab99b (Kees Cook 2019-09-25 16:48:11 -0700 195) printk(KERN_DEFAULT CUT_HERE);
a44f71a9ab99b (Kees Cook 2019-09-25 16:48:11 -0700 196)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 197) if (warning) {
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 198) /* this is a WARN_ON rather than BUG/BUG_ON */
2553b67a1fbe7 (Josh Poimboeuf 2016-03-17 14:23:04 -0700 199) __warn(file, line, (void *)bugaddr, BUG_GET_TAINT(bug), regs,
2553b67a1fbe7 (Josh Poimboeuf 2016-03-17 14:23:04 -0700 200) NULL);
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 201) return BUG_TRAP_TYPE_WARN;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 202) }
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 203)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 204) if (file)
c56ba70331d9f (Fabian Frederick 2014-06-04 16:11:59 -0700 205) pr_crit("kernel BUG at %s:%u!\n", file, line);
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 206) else
0862ca422b79c (Kees Cook 2018-03-09 15:50:59 -0800 207) pr_crit("Kernel BUG at %pB [verbose debug info unavailable]\n",
c56ba70331d9f (Fabian Frederick 2014-06-04 16:11:59 -0700 208) (void *)bugaddr);
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 209)
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 210) return BUG_TRAP_TYPE_BUG;
7664c5a1da471 (Jeremy Fitzhardinge 2006-12-08 02:36:19 -0800 211) }
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 212)
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 213) static void clear_once_table(struct bug_entry *start, struct bug_entry *end)
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 214) {
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 215) struct bug_entry *bug;
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 216)
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 217) for (bug = start; bug < end; bug++)
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 218) bug->flags &= ~BUGFLAG_DONE;
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 219) }
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 220)
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 221) void generic_bug_clear_once(void)
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 222) {
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 223) #ifdef CONFIG_MODULES
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 224) struct module *mod;
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 225)
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 226) rcu_read_lock_sched();
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 227) list_for_each_entry_rcu(mod, &module_bug_list, bug_list)
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 228) clear_once_table(mod->bug_table,
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 229) mod->bug_table + mod->num_bugs);
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 230) rcu_read_unlock_sched();
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 231) #endif
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 232)
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 233) clear_once_table(__start___bug_table, __stop___bug_table);
aaf5dcfb22361 (Andi Kleen 2017-11-17 15:27:06 -0800 234) }