aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sparc/include/asm/ptrace_64.h8
-rw-r--r--arch/sparc64/kernel/process.c36
-rw-r--r--arch/sparc64/mm/ultra.S7
3 files changed, 40 insertions, 11 deletions
diff --git a/arch/sparc/include/asm/ptrace_64.h b/arch/sparc/include/asm/ptrace_64.h
index ec6d45c84cd0..390d92ac67cf 100644
--- a/arch/sparc/include/asm/ptrace_64.h
+++ b/arch/sparc/include/asm/ptrace_64.h
@@ -134,9 +134,9 @@ struct global_reg_snapshot {
134 unsigned long tnpc; 134 unsigned long tnpc;
135 unsigned long o7; 135 unsigned long o7;
136 unsigned long i7; 136 unsigned long i7;
137 unsigned long rpc;
137 struct thread_info *thread; 138 struct thread_info *thread;
138 unsigned long pad1; 139 unsigned long pad1;
139 unsigned long pad2;
140}; 140};
141 141
142#define __ARCH_WANT_COMPAT_SYS_PTRACE 142#define __ARCH_WANT_COMPAT_SYS_PTRACE
@@ -315,9 +315,9 @@ extern void __show_regs(struct pt_regs *);
315#define GR_SNAP_TNPC 0x10 315#define GR_SNAP_TNPC 0x10
316#define GR_SNAP_O7 0x18 316#define GR_SNAP_O7 0x18
317#define GR_SNAP_I7 0x20 317#define GR_SNAP_I7 0x20
318#define GR_SNAP_THREAD 0x28 318#define GR_SNAP_RPC 0x28
319#define GR_SNAP_PAD1 0x30 319#define GR_SNAP_THREAD 0x30
320#define GR_SNAP_PAD2 0x38 320#define GR_SNAP_PAD1 0x38
321 321
322#endif /* __KERNEL__ */ 322#endif /* __KERNEL__ */
323 323
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 0f60547c24d9..fc8137a21ced 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -304,6 +304,19 @@ void show_regs(struct pt_regs *regs)
304struct global_reg_snapshot global_reg_snapshot[NR_CPUS]; 304struct global_reg_snapshot global_reg_snapshot[NR_CPUS];
305static DEFINE_SPINLOCK(global_reg_snapshot_lock); 305static DEFINE_SPINLOCK(global_reg_snapshot_lock);
306 306
307static bool kstack_valid(struct thread_info *tp, struct reg_window *rw)
308{
309 unsigned long thread_base, fp;
310
311 thread_base = (unsigned long) tp;
312 fp = (unsigned long) rw;
313
314 if (fp < (thread_base + sizeof(struct thread_info)) ||
315 fp >= (thread_base + THREAD_SIZE))
316 return false;
317 return true;
318}
319
307static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs, 320static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs,
308 int this_cpu) 321 int this_cpu)
309{ 322{
@@ -315,14 +328,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]; 328 global_reg_snapshot[this_cpu].o7 = regs->u_regs[UREG_I7];
316 329
317 if (regs->tstate & TSTATE_PRIV) { 330 if (regs->tstate & TSTATE_PRIV) {
331 struct thread_info *tp = current_thread_info();
318 struct reg_window *rw; 332 struct reg_window *rw;
319 333
320 rw = (struct reg_window *) 334 rw = (struct reg_window *)
321 (regs->u_regs[UREG_FP] + STACK_BIAS); 335 (regs->u_regs[UREG_FP] + STACK_BIAS);
322 global_reg_snapshot[this_cpu].i7 = rw->ins[7]; 336 if (kstack_valid(tp, rw)) {
323 } else 337 global_reg_snapshot[this_cpu].i7 = rw->ins[7];
338 rw = (struct reg_window *)
339 (rw->ins[6] + STACK_BIAS);
340 if (kstack_valid(tp, rw))
341 global_reg_snapshot[this_cpu].rpc = rw->ins[7];
342 }
343 } else {
324 global_reg_snapshot[this_cpu].i7 = 0; 344 global_reg_snapshot[this_cpu].i7 = 0;
325 345 global_reg_snapshot[this_cpu].rpc = 0;
346 }
326 global_reg_snapshot[this_cpu].thread = tp; 347 global_reg_snapshot[this_cpu].thread = tp;
327} 348}
328 349
@@ -375,13 +396,14 @@ static void sysrq_handle_globreg(int key, struct tty_struct *tty)
375 ((tp && tp->task) ? tp->task->pid : -1)); 396 ((tp && tp->task) ? tp->task->pid : -1));
376 397
377 if (gp->tstate & TSTATE_PRIV) { 398 if (gp->tstate & TSTATE_PRIV) {
378 printk(" TPC[%pS] O7[%pS] I7[%pS]\n", 399 printk(" TPC[%pS] O7[%pS] I7[%pS] RPC[%pS]\n",
379 (void *) gp->tpc, 400 (void *) gp->tpc,
380 (void *) gp->o7, 401 (void *) gp->o7,
381 (void *) gp->i7); 402 (void *) gp->i7,
403 (void *) gp->rpc);
382 } else { 404 } else {
383 printk(" TPC[%lx] O7[%lx] I7[%lx]\n", 405 printk(" TPC[%lx] O7[%lx] I7[%lx] RPC[%lx]\n",
384 gp->tpc, gp->o7, gp->i7); 406 gp->tpc, gp->o7, gp->i7, gp->rpc);
385 } 407 }
386 } 408 }
387 409
diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S
index 4c8ca131ffaf..77ba88597cc5 100644
--- a/arch/sparc64/mm/ultra.S
+++ b/arch/sparc64/mm/ultra.S
@@ -531,6 +531,13 @@ xcall_fetch_glob_regs:
531 stx %g7, [%g1 + GR_SNAP_TNPC] 531 stx %g7, [%g1 + GR_SNAP_TNPC]
532 stx %o7, [%g1 + GR_SNAP_O7] 532 stx %o7, [%g1 + GR_SNAP_O7]
533 stx %i7, [%g1 + GR_SNAP_I7] 533 stx %i7, [%g1 + GR_SNAP_I7]
534 /* Don't try this at home kids... */
535 rdpr %cwp, %g2
536 sub %g2, 1, %g7
537 wrpr %g7, %cwp
538 mov %i7, %g7
539 wrpr %g2, %cwp
540 stx %g7, [%g1 + GR_SNAP_RPC]
534 sethi %hi(trap_block), %g7 541 sethi %hi(trap_block), %g7
535 or %g7, %lo(trap_block), %g7 542 or %g7, %lo(trap_block), %g7
536 sllx %g2, TRAP_BLOCK_SZ_SHIFT, %g2 543 sllx %g2, TRAP_BLOCK_SZ_SHIFT, %g2