aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/mm/fault_64.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-03-01 03:02:23 -0500
committerDavid S. Miller <davem@davemloft.net>2010-03-01 03:02:23 -0500
commit4b17764737bb4ee3364b8bfa2059f51ebc19ccd6 (patch)
tree7f5765e177f9e4fa0122bdf67ac6260499dd19a2 /arch/sparc/mm/fault_64.c
parentc7ec2b585525477f393942ecb18fff1f5e259118 (diff)
sparc: Support show_unhandled_signals.
Just faults right now, will add other traps later. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/mm/fault_64.c')
-rw-r--r--arch/sparc/mm/fault_64.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
index b9d4ff02b8fc..f92ce56a8b22 100644
--- a/arch/sparc/mm/fault_64.c
+++ b/arch/sparc/mm/fault_64.c
@@ -32,6 +32,8 @@
32#include <asm/sections.h> 32#include <asm/sections.h>
33#include <asm/mmu_context.h> 33#include <asm/mmu_context.h>
34 34
35int show_unhandled_signals = 1;
36
35static inline __kprobes int notify_page_fault(struct pt_regs *regs) 37static inline __kprobes int notify_page_fault(struct pt_regs *regs)
36{ 38{
37 int ret = 0; 39 int ret = 0;
@@ -128,22 +130,48 @@ outret:
128 return insn; 130 return insn;
129} 131}
130 132
133static inline void
134show_signal_msg(struct pt_regs *regs, int sig, int code,
135 unsigned long address, struct task_struct *tsk)
136{
137 if (!unhandled_signal(tsk, sig))
138 return;
139
140 if (!printk_ratelimit())
141 return;
142
143 printk("%s%s[%d]: segfault at %lx ip %p (rpc %p) sp %p error %x",
144 task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
145 tsk->comm, task_pid_nr(tsk), address,
146 (void *)regs->tpc, (void *)regs->u_regs[UREG_I7],
147 (void *)regs->u_regs[UREG_FP], code);
148
149 print_vma_addr(KERN_CONT " in ", regs->tpc);
150
151 printk(KERN_CONT "\n");
152}
153
131extern unsigned long compute_effective_address(struct pt_regs *, unsigned int, unsigned int); 154extern unsigned long compute_effective_address(struct pt_regs *, unsigned int, unsigned int);
132 155
133static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, 156static void do_fault_siginfo(int code, int sig, struct pt_regs *regs,
134 unsigned int insn, int fault_code) 157 unsigned int insn, int fault_code)
135{ 158{
159 unsigned long addr;
136 siginfo_t info; 160 siginfo_t info;
137 161
138 info.si_code = code; 162 info.si_code = code;
139 info.si_signo = sig; 163 info.si_signo = sig;
140 info.si_errno = 0; 164 info.si_errno = 0;
141 if (fault_code & FAULT_CODE_ITLB) 165 if (fault_code & FAULT_CODE_ITLB)
142 info.si_addr = (void __user *) regs->tpc; 166 addr = regs->tpc;
143 else 167 else
144 info.si_addr = (void __user *) 168 addr = compute_effective_address(regs, insn, 0);
145 compute_effective_address(regs, insn, 0); 169 info.si_addr = (void __user *) addr;
146 info.si_trapno = 0; 170 info.si_trapno = 0;
171
172 if (unlikely(show_unhandled_signals))
173 show_signal_msg(regs, sig, code, addr, current);
174
147 force_sig_info(sig, &info, current); 175 force_sig_info(sig, &info, current);
148} 176}
149 177