0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 #define pr_fmt(fmt) fmt
0042
0043 #include <linux/list.h>
0044 #include <linux/module.h>
0045 #include <linux/kernel.h>
0046 #include <linux/bug.h>
0047 #include <linux/sched.h>
0048 #include <linux/rculist.h>
0049 #include <linux/ftrace.h>
0050
0051 extern struct bug_entry __start___bug_table[], __stop___bug_table[];
0052
0053 static inline unsigned long bug_addr(const struct bug_entry *bug)
0054 {
0055 #ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
0056 return (unsigned long)&bug->bug_addr_disp + bug->bug_addr_disp;
0057 #else
0058 return bug->bug_addr;
0059 #endif
0060 }
0061
0062 #ifdef CONFIG_MODULES
0063
0064 static LIST_HEAD(module_bug_list);
0065
0066 static struct bug_entry *module_find_bug(unsigned long bugaddr)
0067 {
0068 struct module *mod;
0069 struct bug_entry *bug = NULL;
0070
0071 rcu_read_lock_sched();
0072 list_for_each_entry_rcu(mod, &module_bug_list, bug_list) {
0073 unsigned i;
0074
0075 bug = mod->bug_table;
0076 for (i = 0; i < mod->num_bugs; ++i, ++bug)
0077 if (bugaddr == bug_addr(bug))
0078 goto out;
0079 }
0080 bug = NULL;
0081 out:
0082 rcu_read_unlock_sched();
0083
0084 return bug;
0085 }
0086
0087 void module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
0088 struct module *mod)
0089 {
0090 char *secstrings;
0091 unsigned int i;
0092
0093 mod->bug_table = NULL;
0094 mod->num_bugs = 0;
0095
0096
0097 secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
0098 for (i = 1; i < hdr->e_shnum; i++) {
0099 if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table"))
0100 continue;
0101 mod->bug_table = (void *) sechdrs[i].sh_addr;
0102 mod->num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry);
0103 break;
0104 }
0105
0106
0107
0108
0109
0110
0111
0112
0113 list_add_rcu(&mod->bug_list, &module_bug_list);
0114 }
0115
0116 void module_bug_cleanup(struct module *mod)
0117 {
0118 list_del_rcu(&mod->bug_list);
0119 }
0120
0121 #else
0122
0123 static inline struct bug_entry *module_find_bug(unsigned long bugaddr)
0124 {
0125 return NULL;
0126 }
0127 #endif
0128
0129 void bug_get_file_line(struct bug_entry *bug, const char **file,
0130 unsigned int *line)
0131 {
0132 #ifdef CONFIG_DEBUG_BUGVERBOSE
0133 #ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
0134 *file = (const char *)&bug->file_disp + bug->file_disp;
0135 #else
0136 *file = bug->file;
0137 #endif
0138 *line = bug->line;
0139 #else
0140 *file = NULL;
0141 *line = 0;
0142 #endif
0143 }
0144
0145 struct bug_entry *find_bug(unsigned long bugaddr)
0146 {
0147 struct bug_entry *bug;
0148
0149 for (bug = __start___bug_table; bug < __stop___bug_table; ++bug)
0150 if (bugaddr == bug_addr(bug))
0151 return bug;
0152
0153 return module_find_bug(bugaddr);
0154 }
0155
0156 enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
0157 {
0158 struct bug_entry *bug;
0159 const char *file;
0160 unsigned line, warning, once, done;
0161
0162 if (!is_valid_bugaddr(bugaddr))
0163 return BUG_TRAP_TYPE_NONE;
0164
0165 bug = find_bug(bugaddr);
0166 if (!bug)
0167 return BUG_TRAP_TYPE_NONE;
0168
0169 disable_trace_on_warning();
0170
0171 bug_get_file_line(bug, &file, &line);
0172
0173 warning = (bug->flags & BUGFLAG_WARNING) != 0;
0174 once = (bug->flags & BUGFLAG_ONCE) != 0;
0175 done = (bug->flags & BUGFLAG_DONE) != 0;
0176
0177 if (warning && once) {
0178 if (done)
0179 return BUG_TRAP_TYPE_WARN;
0180
0181
0182
0183
0184 bug->flags |= BUGFLAG_DONE;
0185 }
0186
0187
0188
0189
0190
0191
0192
0193 if ((bug->flags & BUGFLAG_NO_CUT_HERE) == 0)
0194 printk(KERN_DEFAULT CUT_HERE);
0195
0196 if (warning) {
0197
0198 __warn(file, line, (void *)bugaddr, BUG_GET_TAINT(bug), regs,
0199 NULL);
0200 return BUG_TRAP_TYPE_WARN;
0201 }
0202
0203 if (file)
0204 pr_crit("kernel BUG at %s:%u!\n", file, line);
0205 else
0206 pr_crit("Kernel BUG at %pB [verbose debug info unavailable]\n",
0207 (void *)bugaddr);
0208
0209 return BUG_TRAP_TYPE_BUG;
0210 }
0211
0212 static void clear_once_table(struct bug_entry *start, struct bug_entry *end)
0213 {
0214 struct bug_entry *bug;
0215
0216 for (bug = start; bug < end; bug++)
0217 bug->flags &= ~BUGFLAG_DONE;
0218 }
0219
0220 void generic_bug_clear_once(void)
0221 {
0222 #ifdef CONFIG_MODULES
0223 struct module *mod;
0224
0225 rcu_read_lock_sched();
0226 list_for_each_entry_rcu(mod, &module_bug_list, bug_list)
0227 clear_once_table(mod->bug_table,
0228 mod->bug_table + mod->num_bugs);
0229 rcu_read_unlock_sched();
0230 #endif
0231
0232 clear_once_table(__start___bug_table, __stop___bug_table);
0233 }