The patch titled Use generic BUG for powerpc has been added to the -mm tree. Its filename is use-generic-bug-for-powerpc.patch See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this ------------------------------------------------------ Subject: Use generic BUG for powerpc From: Jeremy Fitzhardinge <jeremy@xxxxxxxx> This makes powerpc use the generic BUG machinery. Since the generic BUG machinery is just the old powerpc code repurposed, there are no functional changes. There is an overall reduction of code, since module_32/64 duplicated several functions. Signed-off-by: Jeremy Fitzhardinge <jeremy@xxxxxxxx> Cc: Andrew Morton <akpm@xxxxxxxx> Cc: Andi Kleen <ak@xxxxxx> Cc: Hugh Dickens <hugh@xxxxxxxxxxx> Cc: Michael Ellerman <michael@xxxxxxxxxxxxxx> Cc: Paul Mackerras <paulus@xxxxxxxxx> Cc: Benjamin Herrenschmidt <benh@xxxxxxxxxxxxxxxxxxx> Cc: Rusty Russell <rusty@xxxxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- arch/powerpc/Kconfig | 5 +++ arch/powerpc/kernel/module_32.c | 43 +--------------------------- arch/powerpc/kernel/module_64.c | 43 +--------------------------- arch/powerpc/kernel/traps.c | 30 +++---------------- arch/powerpc/kernel/vmlinux.lds.S | 6 --- include/asm-powerpc/bug.h | 20 +++++++++++++ 6 files changed, 37 insertions(+), 110 deletions(-) diff -puN arch/powerpc/Kconfig~use-generic-bug-for-powerpc arch/powerpc/Kconfig --- a/arch/powerpc/Kconfig~use-generic-bug-for-powerpc +++ a/arch/powerpc/Kconfig @@ -99,6 +99,11 @@ config AUDIT_ARCH bool default y +config GENERIC_BUG + bool + default y + depends on BUG + config DEFAULT_UIMAGE bool help diff -puN arch/powerpc/kernel/module_32.c~use-generic-bug-for-powerpc arch/powerpc/kernel/module_32.c --- a/arch/powerpc/kernel/module_32.c~use-generic-bug-for-powerpc +++ a/arch/powerpc/kernel/module_32.c @@ -23,6 +23,7 @@ #include <linux/string.h> #include <linux/kernel.h> #include <linux/cache.h> +#include <linux/bug.h> #if 0 #define DEBUGP printk @@ -273,48 +274,10 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { - char *secstrings; - unsigned int i; - - me->arch.bug_table = NULL; - me->arch.num_bugs = 0; - - /* Find the __bug_table section, if present */ - secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; - for (i = 1; i < hdr->e_shnum; i++) { - if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table")) - continue; - me->arch.bug_table = (void *) sechdrs[i].sh_addr; - me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry); - break; - } - - /* - * Strictly speaking this should have a spinlock to protect against - * traversals, but since we only traverse on BUG()s, a spinlock - * could potentially lead to deadlock and thus be counter-productive. - */ - list_add(&me->arch.bug_list, &module_bug_list); - - return 0; + return module_bug_finalize(hdr, sechdrs, me); } void module_arch_cleanup(struct module *mod) { - list_del(&mod->arch.bug_list); -} - -struct bug_entry *module_find_bug(unsigned long bugaddr) -{ - struct mod_arch_specific *mod; - unsigned int i; - struct bug_entry *bug; - - list_for_each_entry(mod, &module_bug_list, bug_list) { - bug = mod->bug_table; - for (i = 0; i < mod->num_bugs; ++i, ++bug) - if (bugaddr == bug->bug_addr) - return bug; - } - return NULL; + module_bug_cleanup(mod); } diff -puN arch/powerpc/kernel/module_64.c~use-generic-bug-for-powerpc arch/powerpc/kernel/module_64.c --- a/arch/powerpc/kernel/module_64.c~use-generic-bug-for-powerpc +++ a/arch/powerpc/kernel/module_64.c @@ -20,6 +20,7 @@ #include <linux/moduleloader.h> #include <linux/err.h> #include <linux/vmalloc.h> +#include <linux/bug.h> #include <asm/module.h> #include <asm/uaccess.h> @@ -416,48 +417,10 @@ LIST_HEAD(module_bug_list); int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { - char *secstrings; - unsigned int i; - - me->arch.bug_table = NULL; - me->arch.num_bugs = 0; - - /* Find the __bug_table section, if present */ - secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; - for (i = 1; i < hdr->e_shnum; i++) { - if (strcmp(secstrings+sechdrs[i].sh_name, "__bug_table")) - continue; - me->arch.bug_table = (void *) sechdrs[i].sh_addr; - me->arch.num_bugs = sechdrs[i].sh_size / sizeof(struct bug_entry); - break; - } - - /* - * Strictly speaking this should have a spinlock to protect against - * traversals, but since we only traverse on BUG()s, a spinlock - * could potentially lead to deadlock and thus be counter-productive. - */ - list_add(&me->arch.bug_list, &module_bug_list); - - return 0; + return module_bug_finalize(hdr, sechdrs, me); } void module_arch_cleanup(struct module *mod) { - list_del(&mod->arch.bug_list); -} - -struct bug_entry *module_find_bug(unsigned long bugaddr) -{ - struct mod_arch_specific *mod; - unsigned int i; - struct bug_entry *bug; - - list_for_each_entry(mod, &module_bug_list, bug_list) { - bug = mod->bug_table; - for (i = 0; i < mod->num_bugs; ++i, ++bug) - if (bugaddr == bug->bug_addr) - return bug; - } - return NULL; + module_bug_cleanup(mod); } diff -puN arch/powerpc/kernel/traps.c~use-generic-bug-for-powerpc arch/powerpc/kernel/traps.c --- a/arch/powerpc/kernel/traps.c~use-generic-bug-for-powerpc +++ a/arch/powerpc/kernel/traps.c @@ -754,31 +754,9 @@ struct bug_entry *find_bug(unsigned long return module_find_bug(bugaddr); } -static int check_bug_trap(struct pt_regs *regs) +int is_valid_bugaddr(unsigned long addr) { - struct bug_entry *bug; - unsigned long addr; - - if (regs->msr & MSR_PR) - return 0; /* not in kernel */ - addr = regs->nip; /* address of trap instruction */ - if (addr < PAGE_OFFSET) - return 0; - bug = find_bug(regs->nip); - if (bug == NULL) - return 0; - if (bug->line & BUG_WARNING_TRAP) { - /* this is a WARN_ON rather than BUG/BUG_ON */ - printk(KERN_ERR "Badness in %s at %s:%ld\n", - bug->function, bug->file, - bug->line & ~BUG_WARNING_TRAP); - dump_stack(); - return 1; - } - printk(KERN_CRIT "kernel BUG in %s at %s:%ld!\n", - bug->function, bug->file, bug->line); - - return 0; + return addr >= PAGE_OFFSET; } void __kprobes program_check_exception(struct pt_regs *regs) @@ -812,7 +790,9 @@ void __kprobes program_check_exception(s return; if (debugger_bpt(regs)) return; - if (check_bug_trap(regs)) { + + if (!(regs->msr & MSR_PR) && /* not user-mode */ + report_bug(regs->nip)) { regs->nip += 4; return; } diff -puN arch/powerpc/kernel/vmlinux.lds.S~use-generic-bug-for-powerpc arch/powerpc/kernel/vmlinux.lds.S --- a/arch/powerpc/kernel/vmlinux.lds.S~use-generic-bug-for-powerpc +++ a/arch/powerpc/kernel/vmlinux.lds.S @@ -61,11 +61,7 @@ SECTIONS __stop___ex_table = .; } - __bug_table : { - __start___bug_table = .; - *(__bug_table) - __stop___bug_table = .; - } + BUG_TABLE /* * Init sections discarded at runtime diff -puN include/asm-powerpc/bug.h~use-generic-bug-for-powerpc include/asm-powerpc/bug.h --- a/include/asm-powerpc/bug.h~use-generic-bug-for-powerpc +++ a/include/asm-powerpc/bug.h @@ -30,6 +30,26 @@ struct bug_entry *find_bug(unsigned long #ifdef CONFIG_BUG +static inline int is_warning_bug(const struct bug_entry *bug) +{ + return bug->line & BUG_WARNING_TRAP; +} + +static inline const char *bug_get_function(const struct bug_entry *bug) +{ + return bug->function; +} + +static inline const char *bug_get_file(const struct bug_entry *bug) +{ + return bug->file; +} + +static inline unsigned bug_get_line(const struct bug_entry *bug) +{ + return (unsigned)(bug->line & ~BUG_WARNING_TRAP); +} + /* * BUG_ON() and WARN_ON() do their best to cooperate with compile-time * optimisations. However depending on the complexity of the condition _ Patches currently in -mm which might be from jeremy@xxxxxxxx are origin.patch x86-remove-default_ldt-and-simplify-ldt-setting.patch generic-bug-handling.patch use-generic-bug-for-i386.patch use-generic-bug-for-x86-64.patch use-generic-bug-for-powerpc.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html