diff options
Diffstat (limited to 'arch/sparc64/kernel/process.c')
-rw-r--r-- | arch/sparc64/kernel/process.c | 36 |
1 files changed, 29 insertions, 7 deletions
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) | |||
304 | struct global_reg_snapshot global_reg_snapshot[NR_CPUS]; | 304 | struct global_reg_snapshot global_reg_snapshot[NR_CPUS]; |
305 | static DEFINE_SPINLOCK(global_reg_snapshot_lock); | 305 | static DEFINE_SPINLOCK(global_reg_snapshot_lock); |
306 | 306 | ||
307 | static 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 | |||
307 | static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs, | 320 | static 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 | ||