Back to home page

LXR

 
 

    


0001 /*
0002   Generic support for BUG()
0003 
0004   This respects the following config options:
0005 
0006   CONFIG_BUG - emit BUG traps.  Nothing happens without this.
0007   CONFIG_GENERIC_BUG - enable this code.
0008   CONFIG_GENERIC_BUG_RELATIVE_POINTERS - use 32-bit pointers relative to
0009     the containing struct bug_entry for bug_addr and file.
0010   CONFIG_DEBUG_BUGVERBOSE - emit full file+line information for each BUG
0011 
0012   CONFIG_BUG and CONFIG_DEBUG_BUGVERBOSE are potentially user-settable
0013   (though they're generally always on).
0014 
0015   CONFIG_GENERIC_BUG is set by each architecture using this code.
0016 
0017   To use this, your architecture must:
0018 
0019   1. Set up the config options:
0020      - Enable CONFIG_GENERIC_BUG if CONFIG_BUG
0021 
0022   2. Implement BUG (and optionally BUG_ON, WARN, WARN_ON)
0023      - Define HAVE_ARCH_BUG
0024      - Implement BUG() to generate a faulting instruction
0025      - NOTE: struct bug_entry does not have "file" or "line" entries
0026        when CONFIG_DEBUG_BUGVERBOSE is not enabled, so you must generate
0027        the values accordingly.
0028 
0029   3. Implement the trap
0030      - In the illegal instruction trap handler (typically), verify
0031        that the fault was in kernel mode, and call report_bug()
0032      - report_bug() will return whether it was a false alarm, a warning,
0033        or an actual bug.
0034      - You must implement the is_valid_bugaddr(bugaddr) callback which
0035        returns true if the eip is a real kernel address, and it points
0036        to the expected BUG trap instruction.
0037 
0038     Jeremy Fitzhardinge <jeremy@goop.org> 2006
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 
0049 extern const struct bug_entry __start___bug_table[], __stop___bug_table[];
0050 
0051 static inline unsigned long bug_addr(const struct bug_entry *bug)
0052 {
0053 #ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
0054     return bug->bug_addr;
0055 #else
0056     return (unsigned long)bug + bug->bug_addr_disp;
0057 #endif
0058 }
0059 
0060 #ifdef CONFIG_MODULES
0061 /* Updates are protected by module mutex */
0062 static LIST_HEAD(module_bug_list);
0063 
0064 static const struct bug_entry *module_find_bug(unsigned long bugaddr)
0065 {
0066     struct module *mod;
0067     const struct bug_entry *bug = NULL;
0068 
0069     rcu_read_lock_sched();
0070     list_for_each_entry_rcu(mod, &module_bug_list, bug_list) {
0071         unsigned i;
0072 
0073         bug = mod->bug_table;
0074         for (i = 0; i < mod->num_bugs; ++i, ++bug)
0075             if (bugaddr == bug_addr(bug))
0076                 goto out;
0077     }
0078     bug = NULL;
0079 out:
0080     rcu_read_unlock_sched();
0081 
0082     return bug;
0083 }
0084 
0085 void module_bug_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
0086              struct module *mod)
0087 {
0088     char *secstrings;
0089     unsigned int i;
0090 
0091     lockdep_assert_held(&module_mutex);
0092 
0093     mod->bug_table = NULL;
0094     mod->num_bugs = 0;
0095 
0096     /* Find the __bug_table section, if present */
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      * Strictly speaking this should have a spinlock to protect against
0108      * traversals, but since we only traverse on BUG()s, a spinlock
0109      * could potentially lead to deadlock and thus be counter-productive.
0110      * Thus, this uses RCU to safely manipulate the bug list, since BUG
0111      * must run in non-interruptive state.
0112      */
0113     list_add_rcu(&mod->bug_list, &module_bug_list);
0114 }
0115 
0116 void module_bug_cleanup(struct module *mod)
0117 {
0118     lockdep_assert_held(&module_mutex);
0119     list_del_rcu(&mod->bug_list);
0120 }
0121 
0122 #else
0123 
0124 static inline const struct bug_entry *module_find_bug(unsigned long bugaddr)
0125 {
0126     return NULL;
0127 }
0128 #endif
0129 
0130 const struct bug_entry *find_bug(unsigned long bugaddr)
0131 {
0132     const struct bug_entry *bug;
0133 
0134     for (bug = __start___bug_table; bug < __stop___bug_table; ++bug)
0135         if (bugaddr == bug_addr(bug))
0136             return bug;
0137 
0138     return module_find_bug(bugaddr);
0139 }
0140 
0141 enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
0142 {
0143     const struct bug_entry *bug;
0144     const char *file;
0145     unsigned line, warning;
0146 
0147     if (!is_valid_bugaddr(bugaddr))
0148         return BUG_TRAP_TYPE_NONE;
0149 
0150     bug = find_bug(bugaddr);
0151 
0152     file = NULL;
0153     line = 0;
0154     warning = 0;
0155 
0156     if (bug) {
0157 #ifdef CONFIG_DEBUG_BUGVERBOSE
0158 #ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
0159         file = bug->file;
0160 #else
0161         file = (const char *)bug + bug->file_disp;
0162 #endif
0163         line = bug->line;
0164 #endif
0165         warning = (bug->flags & BUGFLAG_WARNING) != 0;
0166     }
0167 
0168     if (warning) {
0169         /* this is a WARN_ON rather than BUG/BUG_ON */
0170         __warn(file, line, (void *)bugaddr, BUG_GET_TAINT(bug), regs,
0171                NULL);
0172         return BUG_TRAP_TYPE_WARN;
0173     }
0174 
0175     printk(KERN_DEFAULT "------------[ cut here ]------------\n");
0176 
0177     if (file)
0178         pr_crit("kernel BUG at %s:%u!\n", file, line);
0179     else
0180         pr_crit("Kernel BUG at %p [verbose debug info unavailable]\n",
0181             (void *)bugaddr);
0182 
0183     return BUG_TRAP_TYPE_BUG;
0184 }