aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/process.c')
-rw-r--r--arch/sparc64/kernel/process.c110
1 files changed, 35 insertions, 75 deletions
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 8a9cd3e165b9..7f5debdc5fed 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -52,8 +52,6 @@
52#include <asm/irq_regs.h> 52#include <asm/irq_regs.h>
53#include <asm/smp.h> 53#include <asm/smp.h>
54 54
55/* #define VERBOSE_SHOWREGS */
56
57static void sparc64_yield(int cpu) 55static void sparc64_yield(int cpu)
58{ 56{
59 if (tlb_type != hypervisor) 57 if (tlb_type != hypervisor)
@@ -213,22 +211,8 @@ static void show_regwindow(struct pt_regs *regs)
213 printk("I7: <%pS>\n", (void *) rwk->ins[7]); 211 printk("I7: <%pS>\n", (void *) rwk->ins[7]);
214} 212}
215 213
216#ifdef CONFIG_SMP 214void show_regs(struct pt_regs *regs)
217static DEFINE_SPINLOCK(regdump_lock);
218#endif
219
220void __show_regs(struct pt_regs * regs)
221{ 215{
222#ifdef CONFIG_SMP
223 unsigned long flags;
224
225 /* Protect against xcall ipis which might lead to livelock on the lock */
226 __asm__ __volatile__("rdpr %%pstate, %0\n\t"
227 "wrpr %0, %1, %%pstate"
228 : "=r" (flags)
229 : "i" (PSTATE_IE));
230 spin_lock(&regdump_lock);
231#endif
232 printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %08x %s\n", regs->tstate, 216 printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %08x %s\n", regs->tstate,
233 regs->tpc, regs->tnpc, regs->y, print_tainted()); 217 regs->tpc, regs->tnpc, regs->y, print_tainted());
234 printk("TPC: <%pS>\n", (void *) regs->tpc); 218 printk("TPC: <%pS>\n", (void *) regs->tpc);
@@ -246,64 +230,24 @@ void __show_regs(struct pt_regs * regs)
246 regs->u_regs[15]); 230 regs->u_regs[15]);
247 printk("RPC: <%pS>\n", (void *) regs->u_regs[15]); 231 printk("RPC: <%pS>\n", (void *) regs->u_regs[15]);
248 show_regwindow(regs); 232 show_regwindow(regs);
249#ifdef CONFIG_SMP
250 spin_unlock(&regdump_lock);
251 __asm__ __volatile__("wrpr %0, 0, %%pstate"
252 : : "r" (flags));
253#endif
254} 233}
255 234
256#ifdef VERBOSE_SHOWREGS 235struct global_reg_snapshot global_reg_snapshot[NR_CPUS];
257static void idump_from_user (unsigned int *pc) 236static DEFINE_SPINLOCK(global_reg_snapshot_lock);
258{
259 int i;
260 int code;
261
262 if((((unsigned long) pc) & 3))
263 return;
264
265 pc -= 3;
266 for(i = -3; i < 6; i++) {
267 get_user(code, pc);
268 printk("%c%08x%c",i?' ':'<',code,i?' ':'>');
269 pc++;
270 }
271 printk("\n");
272}
273#endif
274 237
275void show_regs(struct pt_regs *regs) 238static bool kstack_valid(struct thread_info *tp, struct reg_window *rw)
276{ 239{
277#ifdef VERBOSE_SHOWREGS 240 unsigned long thread_base, fp;
278 extern long etrap, etraptl1;
279#endif
280 __show_regs(regs);
281#if 0
282#ifdef CONFIG_SMP
283 {
284 extern void smp_report_regs(void);
285 241
286 smp_report_regs(); 242 thread_base = (unsigned long) tp;
287 } 243 fp = (unsigned long) rw;
288#endif
289#endif
290 244
291#ifdef VERBOSE_SHOWREGS 245 if (fp < (thread_base + sizeof(struct thread_info)) ||
292 if (regs->tpc >= &etrap && regs->tpc < &etraptl1 && 246 fp >= (thread_base + THREAD_SIZE))
293 regs->u_regs[14] >= (long)current - PAGE_SIZE && 247 return false;
294 regs->u_regs[14] < (long)current + 6 * PAGE_SIZE) { 248 return true;
295 printk ("*********parent**********\n");
296 __show_regs((struct pt_regs *)(regs->u_regs[14] + PTREGS_OFF));
297 idump_from_user(((struct pt_regs *)(regs->u_regs[14] + PTREGS_OFF))->tpc);
298 printk ("*********endpar**********\n");
299 }
300#endif
301} 249}
302 250
303#ifdef CONFIG_MAGIC_SYSRQ
304struct global_reg_snapshot global_reg_snapshot[NR_CPUS];
305static DEFINE_SPINLOCK(global_reg_snapshot_lock);
306
307static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs, 251static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs,
308 int this_cpu) 252 int this_cpu)
309{ 253{
@@ -315,14 +259,22 @@ static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs,
315 global_reg_snapshot[this_cpu].o7 = regs->u_regs[UREG_I7]; 259 global_reg_snapshot[this_cpu].o7 = regs->u_regs[UREG_I7];
316 260
317 if (regs->tstate & TSTATE_PRIV) { 261 if (regs->tstate & TSTATE_PRIV) {
262 struct thread_info *tp = current_thread_info();
318 struct reg_window *rw; 263 struct reg_window *rw;
319 264
320 rw = (struct reg_window *) 265 rw = (struct reg_window *)
321 (regs->u_regs[UREG_FP] + STACK_BIAS); 266 (regs->u_regs[UREG_FP] + STACK_BIAS);
322 global_reg_snapshot[this_cpu].i7 = rw->ins[6]; 267 if (kstack_valid(tp, rw)) {
323 } else 268 global_reg_snapshot[this_cpu].i7 = rw->ins[7];
269 rw = (struct reg_window *)
270 (rw->ins[6] + STACK_BIAS);
271 if (kstack_valid(tp, rw))
272 global_reg_snapshot[this_cpu].rpc = rw->ins[7];
273 }
274 } else {
324 global_reg_snapshot[this_cpu].i7 = 0; 275 global_reg_snapshot[this_cpu].i7 = 0;
325 276 global_reg_snapshot[this_cpu].rpc = 0;
277 }
326 global_reg_snapshot[this_cpu].thread = tp; 278 global_reg_snapshot[this_cpu].thread = tp;
327} 279}
328 280
@@ -341,7 +293,7 @@ static void __global_reg_poll(struct global_reg_snapshot *gp)
341 } 293 }
342} 294}
343 295
344static void sysrq_handle_globreg(int key, struct tty_struct *tty) 296void __trigger_all_cpu_backtrace(void)
345{ 297{
346 struct thread_info *tp = current_thread_info(); 298 struct thread_info *tp = current_thread_info();
347 struct pt_regs *regs = get_irq_regs(); 299 struct pt_regs *regs = get_irq_regs();
@@ -375,13 +327,14 @@ static void sysrq_handle_globreg(int key, struct tty_struct *tty)
375 ((tp && tp->task) ? tp->task->pid : -1)); 327 ((tp && tp->task) ? tp->task->pid : -1));
376 328
377 if (gp->tstate & TSTATE_PRIV) { 329 if (gp->tstate & TSTATE_PRIV) {
378 printk(" TPC[%pS] O7[%pS] I7[%pS]\n", 330 printk(" TPC[%pS] O7[%pS] I7[%pS] RPC[%pS]\n",
379 (void *) gp->tpc, 331 (void *) gp->tpc,
380 (void *) gp->o7, 332 (void *) gp->o7,
381 (void *) gp->i7); 333 (void *) gp->i7,
334 (void *) gp->rpc);
382 } else { 335 } else {
383 printk(" TPC[%lx] O7[%lx] I7[%lx]\n", 336 printk(" TPC[%lx] O7[%lx] I7[%lx] RPC[%lx]\n",
384 gp->tpc, gp->o7, gp->i7); 337 gp->tpc, gp->o7, gp->i7, gp->rpc);
385 } 338 }
386 } 339 }
387 340
@@ -390,6 +343,13 @@ static void sysrq_handle_globreg(int key, struct tty_struct *tty)
390 spin_unlock_irqrestore(&global_reg_snapshot_lock, flags); 343 spin_unlock_irqrestore(&global_reg_snapshot_lock, flags);
391} 344}
392 345
346#ifdef CONFIG_MAGIC_SYSRQ
347
348static void sysrq_handle_globreg(int key, struct tty_struct *tty)
349{
350 __trigger_all_cpu_backtrace();
351}
352
393static struct sysrq_key_op sparc_globalreg_op = { 353static struct sysrq_key_op sparc_globalreg_op = {
394 .handler = sysrq_handle_globreg, 354 .handler = sysrq_handle_globreg,
395 .help_msg = "Globalregs", 355 .help_msg = "Globalregs",