sparc64: Fix stack tracing through trap frames.

The offset to the pt_regs area was wrong, so we weren't
looking at the right location for the magic cookie.

A trap frame is composed of a "struct sparc_stackf" then
a "struct pt_regs", the code was using "struct reg_window"
instead of "struct sparc_stackf".

Signed-off-by: David S. Miller <davem@davemloft.net>

+14 -10
+7 -5
arch/sparc64/kernel/stacktrace.c
··· 19 fp = ksp + STACK_BIAS; 20 thread_base = (unsigned long) tp; 21 do { 22 - struct reg_window *rw; 23 struct pt_regs *regs; 24 unsigned long pc; 25 ··· 28 fp >= (thread_base + THREAD_SIZE)) 29 break; 30 31 - rw = (struct reg_window *) fp; 32 - regs = (struct pt_regs *) (rw + 1); 33 34 if ((regs->magic & ~0x1ff) == PT_REGS_MAGIC) { 35 pc = regs->tpc; 36 fp = regs->u_regs[UREG_I6] + STACK_BIAS; 37 } else { 38 - pc = rw->ins[7]; 39 - fp = rw->ins[6] + STACK_BIAS; 40 } 41 42 if (trace->skip > 0)
··· 19 fp = ksp + STACK_BIAS; 20 thread_base = (unsigned long) tp; 21 do { 22 + struct sparc_stackf *sf; 23 struct pt_regs *regs; 24 unsigned long pc; 25 ··· 28 fp >= (thread_base + THREAD_SIZE)) 29 break; 30 31 + sf = (struct sparc_stackf *) fp; 32 + regs = (struct pt_regs *) (sf + 1); 33 34 if ((regs->magic & ~0x1ff) == PT_REGS_MAGIC) { 35 + if (!(regs->tstate & TSTATE_PRIV)) 36 + break; 37 pc = regs->tpc; 38 fp = regs->u_regs[UREG_I6] + STACK_BIAS; 39 } else { 40 + pc = sf->callers_pc; 41 + fp = (unsigned long)sf->fp + STACK_BIAS; 42 } 43 44 if (trace->skip > 0)
+7 -5
arch/sparc64/kernel/traps.c
··· 2116 printk("\n"); 2117 #endif 2118 do { 2119 - struct reg_window *rw; 2120 struct pt_regs *regs; 2121 unsigned long pc; 2122 ··· 2124 if (fp < (thread_base + sizeof(struct thread_info)) || 2125 fp >= (thread_base + THREAD_SIZE)) 2126 break; 2127 - rw = (struct reg_window *)fp; 2128 - regs = (struct pt_regs *) (rw + 1); 2129 2130 if ((regs->magic & ~0x1ff) == PT_REGS_MAGIC) { 2131 pc = regs->tpc; 2132 fp = regs->u_regs[UREG_I6] + STACK_BIAS; 2133 } else { 2134 - pc = rw->ins[7]; 2135 - fp = rw->ins[6] + STACK_BIAS; 2136 } 2137 2138 printk(" [%016lx] ", pc);
··· 2116 printk("\n"); 2117 #endif 2118 do { 2119 + struct sparc_stackf *sf; 2120 struct pt_regs *regs; 2121 unsigned long pc; 2122 ··· 2124 if (fp < (thread_base + sizeof(struct thread_info)) || 2125 fp >= (thread_base + THREAD_SIZE)) 2126 break; 2127 + sf = (struct sparc_stackf *) fp; 2128 + regs = (struct pt_regs *) (sf + 1); 2129 2130 if ((regs->magic & ~0x1ff) == PT_REGS_MAGIC) { 2131 + if (!(regs->tstate & TSTATE_PRIV)) 2132 + break; 2133 pc = regs->tpc; 2134 fp = regs->u_regs[UREG_I6] + STACK_BIAS; 2135 } else { 2136 + pc = sf->callers_pc; 2137 + fp = (unsigned long)sf->fp + STACK_BIAS; 2138 } 2139 2140 printk(" [%016lx] ", pc);