diff options
author | David S. Miller <davem@davemloft.net> | 2010-03-01 03:02:23 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-03-01 03:02:23 -0500 |
commit | 4b17764737bb4ee3364b8bfa2059f51ebc19ccd6 (patch) | |
tree | 7f5765e177f9e4fa0122bdf67ac6260499dd19a2 /arch/sparc/mm/fault_64.c | |
parent | c7ec2b585525477f393942ecb18fff1f5e259118 (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.c | 34 |
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 | ||
35 | int show_unhandled_signals = 1; | ||
36 | |||
35 | static inline __kprobes int notify_page_fault(struct pt_regs *regs) | 37 | static 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 | ||
133 | static inline void | ||
134 | show_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 | |||
131 | extern unsigned long compute_effective_address(struct pt_regs *, unsigned int, unsigned int); | 154 | extern unsigned long compute_effective_address(struct pt_regs *, unsigned int, unsigned int); |
132 | 155 | ||
133 | static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, | 156 | static 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 | ||