diff options
Diffstat (limited to 'arch/sparc64/kernel/stacktrace.c')
-rw-r--r-- | arch/sparc64/kernel/stacktrace.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/arch/sparc64/kernel/stacktrace.c b/arch/sparc64/kernel/stacktrace.c index 01b52f561af4..c73ce3f4197e 100644 --- a/arch/sparc64/kernel/stacktrace.c +++ b/arch/sparc64/kernel/stacktrace.c | |||
@@ -19,7 +19,7 @@ void save_stack_trace(struct stack_trace *trace) | |||
19 | fp = ksp + STACK_BIAS; | 19 | fp = ksp + STACK_BIAS; |
20 | thread_base = (unsigned long) tp; | 20 | thread_base = (unsigned long) tp; |
21 | do { | 21 | do { |
22 | struct reg_window *rw; | 22 | struct sparc_stackf *sf; |
23 | struct pt_regs *regs; | 23 | struct pt_regs *regs; |
24 | unsigned long pc; | 24 | unsigned long pc; |
25 | 25 | ||
@@ -28,15 +28,17 @@ void save_stack_trace(struct stack_trace *trace) | |||
28 | fp >= (thread_base + THREAD_SIZE)) | 28 | fp >= (thread_base + THREAD_SIZE)) |
29 | break; | 29 | break; |
30 | 30 | ||
31 | rw = (struct reg_window *) fp; | 31 | sf = (struct sparc_stackf *) fp; |
32 | regs = (struct pt_regs *) (rw + 1); | 32 | regs = (struct pt_regs *) (sf + 1); |
33 | 33 | ||
34 | if ((regs->magic & ~0x1ff) == PT_REGS_MAGIC) { | 34 | if ((regs->magic & ~0x1ff) == PT_REGS_MAGIC) { |
35 | if (!(regs->tstate & TSTATE_PRIV)) | ||
36 | break; | ||
35 | pc = regs->tpc; | 37 | pc = regs->tpc; |
36 | fp = regs->u_regs[UREG_I6] + STACK_BIAS; | 38 | fp = regs->u_regs[UREG_I6] + STACK_BIAS; |
37 | } else { | 39 | } else { |
38 | pc = rw->ins[7]; | 40 | pc = sf->callers_pc; |
39 | fp = rw->ins[6] + STACK_BIAS; | 41 | fp = (unsigned long)sf->fp + STACK_BIAS; |
40 | } | 42 | } |
41 | 43 | ||
42 | if (trace->skip > 0) | 44 | if (trace->skip > 0) |