Loading arch/sparc/mm/fault_32.c +60 −46 Original line number Diff line number Diff line Loading @@ -35,6 +35,8 @@ extern int prom_node_root; int show_unhandled_signals = 1; /* At boot time we determine these two values necessary for setting * up the segment maps and page table entries (pte's). */ Loading Loading @@ -149,6 +151,45 @@ asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc, return 0; } static inline void show_signal_msg(struct pt_regs *regs, int sig, int code, unsigned long address, struct task_struct *tsk) { if (!unhandled_signal(tsk, sig)) return; if (!printk_ratelimit()) return; printk("%s%s[%d]: segfault at %lx ip %p (rpc %p) sp %p error %x", task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, tsk->comm, task_pid_nr(tsk), address, (void *)regs->pc, (void *)regs->u_regs[UREG_I7], (void *)regs->u_regs[UREG_FP], code); print_vma_addr(KERN_CONT " in ", regs->pc); printk(KERN_CONT "\n"); } static void __do_fault_siginfo(int code, int sig, struct pt_regs *regs, unsigned long addr) { siginfo_t info; info.si_signo = sig; info.si_code = code; info.si_errno = 0; info.si_addr = (void __user *) addr; info.si_trapno = 0; if (unlikely(show_unhandled_signals)) show_signal_msg(regs, sig, info.si_code, addr, current); force_sig_info (sig, &info, current); } extern unsigned long safe_compute_effective_address(struct pt_regs *, unsigned int); Loading @@ -168,6 +209,14 @@ static unsigned long compute_si_addr(struct pt_regs *regs, int text_fault) return safe_compute_effective_address(regs, insn); } static noinline void do_fault_siginfo(int code, int sig, struct pt_regs *regs, int text_fault) { unsigned long addr = compute_si_addr(regs, text_fault); __do_fault_siginfo(code, sig, regs, addr); } asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, unsigned long address) { Loading @@ -176,9 +225,8 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, struct mm_struct *mm = tsk->mm; unsigned int fixup; unsigned long g2; siginfo_t info; int from_user = !(regs->psr & PSR_PS); int fault; int fault, code; if(text_fault) address = regs->pc; Loading @@ -195,7 +243,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, if (!ARCH_SUN4C && address >= TASK_SIZE) goto vmalloc_fault; info.si_code = SEGV_MAPERR; code = SEGV_MAPERR; /* * If we're in an interrupt or have no user Loading Loading @@ -229,7 +277,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, * we can handle it.. */ good_area: info.si_code = SEGV_ACCERR; code = SEGV_ACCERR; if(write) { if(!(vma->vm_flags & VM_WRITE)) goto bad_area; Loading Loading @@ -274,17 +322,7 @@ bad_area: bad_area_nosemaphore: /* User mode accesses just cause a SIGSEGV */ if (from_user) { #if 0 printk("Fault whee %s [%d]: segfaults at %08lx pc=%08lx\n", tsk->comm, tsk->pid, address, regs->pc); #endif info.si_signo = SIGSEGV; info.si_errno = 0; /* info.si_code set above to make clear whether this was a SEGV_MAPERR or SEGV_ACCERR fault. */ info.si_addr = (void __user *)compute_si_addr(regs, text_fault); info.si_trapno = 0; force_sig_info (SIGSEGV, &info, tsk); do_fault_siginfo(code, SIGSEGV, regs, text_fault); return; } Loading Loading @@ -335,12 +373,7 @@ out_of_memory: do_sigbus: up_read(&mm->mmap_sem); info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRERR; info.si_addr = (void __user *) compute_si_addr(regs, text_fault); info.si_trapno = 0; force_sig_info (SIGBUS, &info, tsk); do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, text_fault); if (!from_user) goto no_context; Loading Loading @@ -466,14 +499,10 @@ static void force_user_fault(unsigned long address, int write) struct vm_area_struct *vma; struct task_struct *tsk = current; struct mm_struct *mm = tsk->mm; siginfo_t info; int code; info.si_code = SEGV_MAPERR; code = SEGV_MAPERR; #if 0 printk("wf<pid=%d,wr=%d,addr=%08lx>\n", tsk->pid, write, address); #endif down_read(&mm->mmap_sem); vma = find_vma(mm, address); if(!vma) Loading @@ -485,7 +514,7 @@ static void force_user_fault(unsigned long address, int write) if(expand_stack(vma, address)) goto bad_area; good_area: info.si_code = SEGV_ACCERR; code = SEGV_ACCERR; if(write) { if(!(vma->vm_flags & VM_WRITE)) goto bad_area; Loading @@ -502,27 +531,12 @@ good_area: return; bad_area: up_read(&mm->mmap_sem); #if 0 printk("Window whee %s [%d]: segfaults at %08lx\n", tsk->comm, tsk->pid, address); #endif info.si_signo = SIGSEGV; info.si_errno = 0; /* info.si_code set above to make clear whether this was a SEGV_MAPERR or SEGV_ACCERR fault. */ info.si_addr = (void __user *) address; info.si_trapno = 0; force_sig_info (SIGSEGV, &info, tsk); __do_fault_siginfo(code, SIGSEGV, tsk->thread.kregs, address); return; do_sigbus: up_read(&mm->mmap_sem); info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRERR; info.si_addr = (void __user *) address; info.si_trapno = 0; force_sig_info (SIGBUS, &info, tsk); __do_fault_siginfo(BUS_ADRERR, SIGBUS, tsk->thread.kregs, address); } void window_overflow_fault(void) Loading arch/sparc/mm/fault_64.c +31 −3 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ #include <asm/sections.h> #include <asm/mmu_context.h> int show_unhandled_signals = 1; static inline __kprobes int notify_page_fault(struct pt_regs *regs) { int ret = 0; Loading Loading @@ -128,22 +130,48 @@ outret: return insn; } static inline void show_signal_msg(struct pt_regs *regs, int sig, int code, unsigned long address, struct task_struct *tsk) { if (!unhandled_signal(tsk, sig)) return; if (!printk_ratelimit()) return; printk("%s%s[%d]: segfault at %lx ip %p (rpc %p) sp %p error %x", task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, tsk->comm, task_pid_nr(tsk), address, (void *)regs->tpc, (void *)regs->u_regs[UREG_I7], (void *)regs->u_regs[UREG_FP], code); print_vma_addr(KERN_CONT " in ", regs->tpc); printk(KERN_CONT "\n"); } extern unsigned long compute_effective_address(struct pt_regs *, unsigned int, unsigned int); static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, unsigned int insn, int fault_code) { unsigned long addr; siginfo_t info; info.si_code = code; info.si_signo = sig; info.si_errno = 0; if (fault_code & FAULT_CODE_ITLB) info.si_addr = (void __user *) regs->tpc; addr = regs->tpc; else info.si_addr = (void __user *) compute_effective_address(regs, insn, 0); addr = compute_effective_address(regs, insn, 0); info.si_addr = (void __user *) addr; info.si_trapno = 0; if (unlikely(show_unhandled_signals)) show_signal_msg(regs, sig, code, addr, current); force_sig_info(sig, &info, current); } Loading kernel/sysctl.c +1 −1 Original line number Diff line number Diff line Loading @@ -1441,7 +1441,7 @@ static struct ctl_table fs_table[] = { }; static struct ctl_table debug_table[] = { #if defined(CONFIG_X86) || defined(CONFIG_PPC) #if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) { .procname = "exception-trace", .data = &show_unhandled_signals, Loading Loading
arch/sparc/mm/fault_32.c +60 −46 Original line number Diff line number Diff line Loading @@ -35,6 +35,8 @@ extern int prom_node_root; int show_unhandled_signals = 1; /* At boot time we determine these two values necessary for setting * up the segment maps and page table entries (pte's). */ Loading Loading @@ -149,6 +151,45 @@ asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc, return 0; } static inline void show_signal_msg(struct pt_regs *regs, int sig, int code, unsigned long address, struct task_struct *tsk) { if (!unhandled_signal(tsk, sig)) return; if (!printk_ratelimit()) return; printk("%s%s[%d]: segfault at %lx ip %p (rpc %p) sp %p error %x", task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, tsk->comm, task_pid_nr(tsk), address, (void *)regs->pc, (void *)regs->u_regs[UREG_I7], (void *)regs->u_regs[UREG_FP], code); print_vma_addr(KERN_CONT " in ", regs->pc); printk(KERN_CONT "\n"); } static void __do_fault_siginfo(int code, int sig, struct pt_regs *regs, unsigned long addr) { siginfo_t info; info.si_signo = sig; info.si_code = code; info.si_errno = 0; info.si_addr = (void __user *) addr; info.si_trapno = 0; if (unlikely(show_unhandled_signals)) show_signal_msg(regs, sig, info.si_code, addr, current); force_sig_info (sig, &info, current); } extern unsigned long safe_compute_effective_address(struct pt_regs *, unsigned int); Loading @@ -168,6 +209,14 @@ static unsigned long compute_si_addr(struct pt_regs *regs, int text_fault) return safe_compute_effective_address(regs, insn); } static noinline void do_fault_siginfo(int code, int sig, struct pt_regs *regs, int text_fault) { unsigned long addr = compute_si_addr(regs, text_fault); __do_fault_siginfo(code, sig, regs, addr); } asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, unsigned long address) { Loading @@ -176,9 +225,8 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, struct mm_struct *mm = tsk->mm; unsigned int fixup; unsigned long g2; siginfo_t info; int from_user = !(regs->psr & PSR_PS); int fault; int fault, code; if(text_fault) address = regs->pc; Loading @@ -195,7 +243,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, if (!ARCH_SUN4C && address >= TASK_SIZE) goto vmalloc_fault; info.si_code = SEGV_MAPERR; code = SEGV_MAPERR; /* * If we're in an interrupt or have no user Loading Loading @@ -229,7 +277,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, * we can handle it.. */ good_area: info.si_code = SEGV_ACCERR; code = SEGV_ACCERR; if(write) { if(!(vma->vm_flags & VM_WRITE)) goto bad_area; Loading Loading @@ -274,17 +322,7 @@ bad_area: bad_area_nosemaphore: /* User mode accesses just cause a SIGSEGV */ if (from_user) { #if 0 printk("Fault whee %s [%d]: segfaults at %08lx pc=%08lx\n", tsk->comm, tsk->pid, address, regs->pc); #endif info.si_signo = SIGSEGV; info.si_errno = 0; /* info.si_code set above to make clear whether this was a SEGV_MAPERR or SEGV_ACCERR fault. */ info.si_addr = (void __user *)compute_si_addr(regs, text_fault); info.si_trapno = 0; force_sig_info (SIGSEGV, &info, tsk); do_fault_siginfo(code, SIGSEGV, regs, text_fault); return; } Loading Loading @@ -335,12 +373,7 @@ out_of_memory: do_sigbus: up_read(&mm->mmap_sem); info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRERR; info.si_addr = (void __user *) compute_si_addr(regs, text_fault); info.si_trapno = 0; force_sig_info (SIGBUS, &info, tsk); do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, text_fault); if (!from_user) goto no_context; Loading Loading @@ -466,14 +499,10 @@ static void force_user_fault(unsigned long address, int write) struct vm_area_struct *vma; struct task_struct *tsk = current; struct mm_struct *mm = tsk->mm; siginfo_t info; int code; info.si_code = SEGV_MAPERR; code = SEGV_MAPERR; #if 0 printk("wf<pid=%d,wr=%d,addr=%08lx>\n", tsk->pid, write, address); #endif down_read(&mm->mmap_sem); vma = find_vma(mm, address); if(!vma) Loading @@ -485,7 +514,7 @@ static void force_user_fault(unsigned long address, int write) if(expand_stack(vma, address)) goto bad_area; good_area: info.si_code = SEGV_ACCERR; code = SEGV_ACCERR; if(write) { if(!(vma->vm_flags & VM_WRITE)) goto bad_area; Loading @@ -502,27 +531,12 @@ good_area: return; bad_area: up_read(&mm->mmap_sem); #if 0 printk("Window whee %s [%d]: segfaults at %08lx\n", tsk->comm, tsk->pid, address); #endif info.si_signo = SIGSEGV; info.si_errno = 0; /* info.si_code set above to make clear whether this was a SEGV_MAPERR or SEGV_ACCERR fault. */ info.si_addr = (void __user *) address; info.si_trapno = 0; force_sig_info (SIGSEGV, &info, tsk); __do_fault_siginfo(code, SIGSEGV, tsk->thread.kregs, address); return; do_sigbus: up_read(&mm->mmap_sem); info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRERR; info.si_addr = (void __user *) address; info.si_trapno = 0; force_sig_info (SIGBUS, &info, tsk); __do_fault_siginfo(BUS_ADRERR, SIGBUS, tsk->thread.kregs, address); } void window_overflow_fault(void) Loading
arch/sparc/mm/fault_64.c +31 −3 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ #include <asm/sections.h> #include <asm/mmu_context.h> int show_unhandled_signals = 1; static inline __kprobes int notify_page_fault(struct pt_regs *regs) { int ret = 0; Loading Loading @@ -128,22 +130,48 @@ outret: return insn; } static inline void show_signal_msg(struct pt_regs *regs, int sig, int code, unsigned long address, struct task_struct *tsk) { if (!unhandled_signal(tsk, sig)) return; if (!printk_ratelimit()) return; printk("%s%s[%d]: segfault at %lx ip %p (rpc %p) sp %p error %x", task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, tsk->comm, task_pid_nr(tsk), address, (void *)regs->tpc, (void *)regs->u_regs[UREG_I7], (void *)regs->u_regs[UREG_FP], code); print_vma_addr(KERN_CONT " in ", regs->tpc); printk(KERN_CONT "\n"); } extern unsigned long compute_effective_address(struct pt_regs *, unsigned int, unsigned int); static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, unsigned int insn, int fault_code) { unsigned long addr; siginfo_t info; info.si_code = code; info.si_signo = sig; info.si_errno = 0; if (fault_code & FAULT_CODE_ITLB) info.si_addr = (void __user *) regs->tpc; addr = regs->tpc; else info.si_addr = (void __user *) compute_effective_address(regs, insn, 0); addr = compute_effective_address(regs, insn, 0); info.si_addr = (void __user *) addr; info.si_trapno = 0; if (unlikely(show_unhandled_signals)) show_signal_msg(regs, sig, code, addr, current); force_sig_info(sig, &info, current); } Loading
kernel/sysctl.c +1 −1 Original line number Diff line number Diff line Loading @@ -1441,7 +1441,7 @@ static struct ctl_table fs_table[] = { }; static struct ctl_table debug_table[] = { #if defined(CONFIG_X86) || defined(CONFIG_PPC) #if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) { .procname = "exception-trace", .data = &show_unhandled_signals, Loading