Loading arch/parisc/Kconfig +5 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,11 @@ config GENERIC_FIND_NEXT_BIT bool default y config GENERIC_BUG bool default y depends on BUG config GENERIC_HWEIGHT bool default y Loading arch/parisc/kernel/module.c +3 −1 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ #include <linux/fs.h> #include <linux/string.h> #include <linux/kernel.h> #include <linux/bug.h> #include <asm/unwind.h> Loading Loading @@ -851,10 +852,11 @@ int module_finalize(const Elf_Ehdr *hdr, nsyms = newptr - (Elf_Sym *)symhdr->sh_addr; DEBUGP("NEW num_symtab %lu\n", nsyms); symhdr->sh_size = nsyms * sizeof(Elf_Sym); return 0; return module_bug_finalize(hdr, sechdrs, me); } void module_arch_cleanup(struct module *mod) { deregister_unwind_table(mod); module_bug_cleanup(mod); } arch/parisc/kernel/traps.c +38 −47 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include <linux/interrupt.h> #include <linux/console.h> #include <linux/kallsyms.h> #include <linux/bug.h> #include <asm/assembly.h> #include <asm/system.h> Loading @@ -51,7 +52,7 @@ DEFINE_SPINLOCK(pa_dbit_lock); #endif int printbinary(char *buf, unsigned long x, int nbits) static int printbinary(char *buf, unsigned long x, int nbits) { unsigned long mask = 1UL << (nbits - 1); while (mask != 0) { Loading Loading @@ -207,6 +208,11 @@ void show_stack(struct task_struct *task, unsigned long *s) do_show_stack(&info); } int is_valid_bugaddr(unsigned long iaoq) { return 1; } void die_if_kernel(char *str, struct pt_regs *regs, long err) { if (user_mode(regs)) { Loading @@ -225,7 +231,7 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err) oops_in_progress = 1; /* Amuse the user in a SPARC fashion */ printk( if (err) printk( " _______________________________ \n" " < Your System ate a SPARC! Gah! >\n" " ------------------------------- \n" Loading @@ -245,6 +251,7 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err) if (!console_drivers) pdc_console_restart(); if (err) printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n", current->comm, current->pid, str, err); show_regs(regs); Loading Loading @@ -276,61 +283,45 @@ int syscall_ipi(int (*syscall) (struct pt_regs *), struct pt_regs *regs) /* gdb uses break 4,8 */ #define GDB_BREAK_INSN 0x10004 void handle_gdb_break(struct pt_regs *regs, int wot) static void handle_gdb_break(struct pt_regs *regs, int wot) { struct siginfo si; si.si_code = wot; si.si_addr = (void __user *) (regs->iaoq[0] & ~3); si.si_signo = SIGTRAP; si.si_errno = 0; si.si_code = wot; si.si_addr = (void __user *) (regs->iaoq[0] & ~3); force_sig_info(SIGTRAP, &si, current); } void handle_break(unsigned iir, struct pt_regs *regs) static void handle_break(struct pt_regs *regs) { struct siginfo si; unsigned iir = regs->iir; if (unlikely(iir == PARISC_BUG_BREAK_INSN && !user_mode(regs))) { /* check if a BUG() or WARN() trapped here. */ enum bug_trap_type tt; tt = report_bug(regs->iaoq[0] & ~3); if (tt == BUG_TRAP_TYPE_WARN) { regs->iaoq[0] += 4; regs->iaoq[1] += 4; return; /* return to next instruction when WARN_ON(). */ } die_if_kernel("Unknown kernel breakpoint", regs, (tt == BUG_TRAP_TYPE_NONE) ? 9 : 0); } switch(iir) { case 0x00: #ifdef PRINT_USER_FAULTS printk(KERN_DEBUG "break 0,0: pid=%d command='%s'\n", if (unlikely(iir != GDB_BREAK_INSN)) { printk(KERN_DEBUG "break %d,%d: pid=%d command='%s'\n", (iir>>13) & ((1<<13)-1), iir & 31, current->pid, current->comm); #endif die_if_kernel("Breakpoint", regs, 0); #ifdef PRINT_USER_FAULTS show_regs(regs); } #endif si.si_code = TRAP_BRKPT; si.si_addr = (void __user *) (regs->iaoq[0] & ~3); si.si_signo = SIGTRAP; force_sig_info(SIGTRAP, &si, current); break; case GDB_BREAK_INSN: die_if_kernel("Breakpoint", regs, 0); /* send standard GDB signal */ handle_gdb_break(regs, TRAP_BRKPT); break; default: #ifdef PRINT_USER_FAULTS printk(KERN_DEBUG "break %#08x: pid=%d command='%s'\n", iir, current->pid, current->comm); show_regs(regs); #endif si.si_signo = SIGTRAP; si.si_code = TRAP_BRKPT; si.si_addr = (void __user *) (regs->iaoq[0] & ~3); force_sig_info(SIGTRAP, &si, current); return; } } int handle_toc(void) { printk(KERN_CRIT "TOC call.\n"); return 0; } static void default_trap(int code, struct pt_regs *regs) Loading @@ -339,7 +330,7 @@ static void default_trap(int code, struct pt_regs *regs) show_regs(regs); } void (*cpu_lpmc) (int code, struct pt_regs *regs) = default_trap; void (*cpu_lpmc) (int code, struct pt_regs *regs) __read_mostly = default_trap; void transfer_pim_to_trap_frame(struct pt_regs *regs) Loading Loading @@ -576,7 +567,7 @@ void handle_interruption(int code, struct pt_regs *regs) case 9: /* Break instruction trap */ handle_break(regs->iir,regs); handle_break(regs); return; case 10: Loading arch/parisc/kernel/vmlinux.lds.S +2 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,8 @@ SECTIONS RODATA BUG_TABLE /* writeable */ . = ALIGN(ASM_PAGE_SIZE); /* Make sure this is page aligned so that we can properly leave these Loading include/asm-parisc/bug.h +68 −5 Original line number Diff line number Diff line #ifndef _PARISC_BUG_H #define _PARISC_BUG_H /* * Tell the user there is some problem. * The offending file and line are encoded in the __bug_table section. */ #ifdef CONFIG_BUG #define HAVE_ARCH_BUG #define BUG() do { \ printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ dump_stack(); \ panic("BUG!"); \ #define HAVE_ARCH_WARN_ON /* the break instruction is used as BUG() marker. */ #define PARISC_BUG_BREAK_ASM "break 0x1f, 0x1fff" #define PARISC_BUG_BREAK_INSN 0x03ffe01f /* PARISC_BUG_BREAK_ASM */ #ifdef CONFIG_64BIT #define ASM_ULONG_INSN ".dword" #else #define ASM_ULONG_INSN ".word" #endif #ifdef CONFIG_DEBUG_BUGVERBOSE #define BUG() \ do { \ asm volatile("\n" \ "1:\t" PARISC_BUG_BREAK_ASM "\n" \ "\t.pushsection __bug_table,\"a\"\n" \ "2:\t" ASM_ULONG_INSN " 1b, %c0\n" \ "\t.short %c1, %c2\n" \ "\t.org 2b+%c3\n" \ "\t.popsection" \ : : "i" (__FILE__), "i" (__LINE__), \ "i" (0), "i" (sizeof(struct bug_entry)) ); \ for(;;) ; \ } while(0) #else #define BUG() \ do { \ asm volatile(PARISC_BUG_BREAK_ASM : : ); \ for(;;) ; \ } while(0) #endif #define __WARN() \ do { \ asm volatile("\n" \ "1:\t" PARISC_BUG_BREAK_ASM "\n" \ "\t.pushsection __bug_table,\"a\"\n" \ "2:\t" ASM_ULONG_INSN " 1b, %c0\n" \ "\t.short %c1, %c2\n" \ "\t.org 2b+%c3\n" \ "\t.popsection" \ : : "i" (__FILE__), "i" (__LINE__), \ "i" (BUGFLAG_WARNING), \ "i" (sizeof(struct bug_entry)) ); \ } while(0) #define WARN_ON(x) ({ \ typeof(x) __ret_warn_on = (x); \ if (__builtin_constant_p(__ret_warn_on)) { \ if (__ret_warn_on) \ __WARN(); \ } else { \ if (unlikely(__ret_warn_on)) \ __WARN(); \ } \ unlikely(__ret_warn_on); \ }) #endif #include <asm-generic/bug.h> #endif Loading
arch/parisc/Kconfig +5 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,11 @@ config GENERIC_FIND_NEXT_BIT bool default y config GENERIC_BUG bool default y depends on BUG config GENERIC_HWEIGHT bool default y Loading
arch/parisc/kernel/module.c +3 −1 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ #include <linux/fs.h> #include <linux/string.h> #include <linux/kernel.h> #include <linux/bug.h> #include <asm/unwind.h> Loading Loading @@ -851,10 +852,11 @@ int module_finalize(const Elf_Ehdr *hdr, nsyms = newptr - (Elf_Sym *)symhdr->sh_addr; DEBUGP("NEW num_symtab %lu\n", nsyms); symhdr->sh_size = nsyms * sizeof(Elf_Sym); return 0; return module_bug_finalize(hdr, sechdrs, me); } void module_arch_cleanup(struct module *mod) { deregister_unwind_table(mod); module_bug_cleanup(mod); }
arch/parisc/kernel/traps.c +38 −47 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include <linux/interrupt.h> #include <linux/console.h> #include <linux/kallsyms.h> #include <linux/bug.h> #include <asm/assembly.h> #include <asm/system.h> Loading @@ -51,7 +52,7 @@ DEFINE_SPINLOCK(pa_dbit_lock); #endif int printbinary(char *buf, unsigned long x, int nbits) static int printbinary(char *buf, unsigned long x, int nbits) { unsigned long mask = 1UL << (nbits - 1); while (mask != 0) { Loading Loading @@ -207,6 +208,11 @@ void show_stack(struct task_struct *task, unsigned long *s) do_show_stack(&info); } int is_valid_bugaddr(unsigned long iaoq) { return 1; } void die_if_kernel(char *str, struct pt_regs *regs, long err) { if (user_mode(regs)) { Loading @@ -225,7 +231,7 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err) oops_in_progress = 1; /* Amuse the user in a SPARC fashion */ printk( if (err) printk( " _______________________________ \n" " < Your System ate a SPARC! Gah! >\n" " ------------------------------- \n" Loading @@ -245,6 +251,7 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err) if (!console_drivers) pdc_console_restart(); if (err) printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n", current->comm, current->pid, str, err); show_regs(regs); Loading Loading @@ -276,61 +283,45 @@ int syscall_ipi(int (*syscall) (struct pt_regs *), struct pt_regs *regs) /* gdb uses break 4,8 */ #define GDB_BREAK_INSN 0x10004 void handle_gdb_break(struct pt_regs *regs, int wot) static void handle_gdb_break(struct pt_regs *regs, int wot) { struct siginfo si; si.si_code = wot; si.si_addr = (void __user *) (regs->iaoq[0] & ~3); si.si_signo = SIGTRAP; si.si_errno = 0; si.si_code = wot; si.si_addr = (void __user *) (regs->iaoq[0] & ~3); force_sig_info(SIGTRAP, &si, current); } void handle_break(unsigned iir, struct pt_regs *regs) static void handle_break(struct pt_regs *regs) { struct siginfo si; unsigned iir = regs->iir; if (unlikely(iir == PARISC_BUG_BREAK_INSN && !user_mode(regs))) { /* check if a BUG() or WARN() trapped here. */ enum bug_trap_type tt; tt = report_bug(regs->iaoq[0] & ~3); if (tt == BUG_TRAP_TYPE_WARN) { regs->iaoq[0] += 4; regs->iaoq[1] += 4; return; /* return to next instruction when WARN_ON(). */ } die_if_kernel("Unknown kernel breakpoint", regs, (tt == BUG_TRAP_TYPE_NONE) ? 9 : 0); } switch(iir) { case 0x00: #ifdef PRINT_USER_FAULTS printk(KERN_DEBUG "break 0,0: pid=%d command='%s'\n", if (unlikely(iir != GDB_BREAK_INSN)) { printk(KERN_DEBUG "break %d,%d: pid=%d command='%s'\n", (iir>>13) & ((1<<13)-1), iir & 31, current->pid, current->comm); #endif die_if_kernel("Breakpoint", regs, 0); #ifdef PRINT_USER_FAULTS show_regs(regs); } #endif si.si_code = TRAP_BRKPT; si.si_addr = (void __user *) (regs->iaoq[0] & ~3); si.si_signo = SIGTRAP; force_sig_info(SIGTRAP, &si, current); break; case GDB_BREAK_INSN: die_if_kernel("Breakpoint", regs, 0); /* send standard GDB signal */ handle_gdb_break(regs, TRAP_BRKPT); break; default: #ifdef PRINT_USER_FAULTS printk(KERN_DEBUG "break %#08x: pid=%d command='%s'\n", iir, current->pid, current->comm); show_regs(regs); #endif si.si_signo = SIGTRAP; si.si_code = TRAP_BRKPT; si.si_addr = (void __user *) (regs->iaoq[0] & ~3); force_sig_info(SIGTRAP, &si, current); return; } } int handle_toc(void) { printk(KERN_CRIT "TOC call.\n"); return 0; } static void default_trap(int code, struct pt_regs *regs) Loading @@ -339,7 +330,7 @@ static void default_trap(int code, struct pt_regs *regs) show_regs(regs); } void (*cpu_lpmc) (int code, struct pt_regs *regs) = default_trap; void (*cpu_lpmc) (int code, struct pt_regs *regs) __read_mostly = default_trap; void transfer_pim_to_trap_frame(struct pt_regs *regs) Loading Loading @@ -576,7 +567,7 @@ void handle_interruption(int code, struct pt_regs *regs) case 9: /* Break instruction trap */ handle_break(regs->iir,regs); handle_break(regs); return; case 10: Loading
arch/parisc/kernel/vmlinux.lds.S +2 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,8 @@ SECTIONS RODATA BUG_TABLE /* writeable */ . = ALIGN(ASM_PAGE_SIZE); /* Make sure this is page aligned so that we can properly leave these Loading
include/asm-parisc/bug.h +68 −5 Original line number Diff line number Diff line #ifndef _PARISC_BUG_H #define _PARISC_BUG_H /* * Tell the user there is some problem. * The offending file and line are encoded in the __bug_table section. */ #ifdef CONFIG_BUG #define HAVE_ARCH_BUG #define BUG() do { \ printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ dump_stack(); \ panic("BUG!"); \ #define HAVE_ARCH_WARN_ON /* the break instruction is used as BUG() marker. */ #define PARISC_BUG_BREAK_ASM "break 0x1f, 0x1fff" #define PARISC_BUG_BREAK_INSN 0x03ffe01f /* PARISC_BUG_BREAK_ASM */ #ifdef CONFIG_64BIT #define ASM_ULONG_INSN ".dword" #else #define ASM_ULONG_INSN ".word" #endif #ifdef CONFIG_DEBUG_BUGVERBOSE #define BUG() \ do { \ asm volatile("\n" \ "1:\t" PARISC_BUG_BREAK_ASM "\n" \ "\t.pushsection __bug_table,\"a\"\n" \ "2:\t" ASM_ULONG_INSN " 1b, %c0\n" \ "\t.short %c1, %c2\n" \ "\t.org 2b+%c3\n" \ "\t.popsection" \ : : "i" (__FILE__), "i" (__LINE__), \ "i" (0), "i" (sizeof(struct bug_entry)) ); \ for(;;) ; \ } while(0) #else #define BUG() \ do { \ asm volatile(PARISC_BUG_BREAK_ASM : : ); \ for(;;) ; \ } while(0) #endif #define __WARN() \ do { \ asm volatile("\n" \ "1:\t" PARISC_BUG_BREAK_ASM "\n" \ "\t.pushsection __bug_table,\"a\"\n" \ "2:\t" ASM_ULONG_INSN " 1b, %c0\n" \ "\t.short %c1, %c2\n" \ "\t.org 2b+%c3\n" \ "\t.popsection" \ : : "i" (__FILE__), "i" (__LINE__), \ "i" (BUGFLAG_WARNING), \ "i" (sizeof(struct bug_entry)) ); \ } while(0) #define WARN_ON(x) ({ \ typeof(x) __ret_warn_on = (x); \ if (__builtin_constant_p(__ret_warn_on)) { \ if (__ret_warn_on) \ __WARN(); \ } else { \ if (unlikely(__ret_warn_on)) \ __WARN(); \ } \ unlikely(__ret_warn_on); \ }) #endif #include <asm-generic/bug.h> #endif