diff options
Diffstat (limited to 'arch/xtensa/kernel/traps.c')
-rw-r--r-- | arch/xtensa/kernel/traps.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index 9f0b71189e94..ba9ab9349782 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c | |||
@@ -369,6 +369,18 @@ void show_regs(struct pt_regs * regs) | |||
369 | regs->syscall); | 369 | regs->syscall); |
370 | } | 370 | } |
371 | 371 | ||
372 | static __always_inline unsigned long *stack_pointer(struct task_struct *task) | ||
373 | { | ||
374 | unsigned long *sp; | ||
375 | |||
376 | if (!task || task == current) | ||
377 | __asm__ __volatile__ ("mov %0, a1\n" : "=a"(sp)); | ||
378 | else | ||
379 | sp = (unsigned long *)task->thread.sp; | ||
380 | |||
381 | return sp; | ||
382 | } | ||
383 | |||
372 | void show_trace(struct task_struct *task, unsigned long *sp) | 384 | void show_trace(struct task_struct *task, unsigned long *sp) |
373 | { | 385 | { |
374 | unsigned long a0, a1, pc; | 386 | unsigned long a0, a1, pc; |
@@ -377,7 +389,7 @@ void show_trace(struct task_struct *task, unsigned long *sp) | |||
377 | if (sp) | 389 | if (sp) |
378 | a1 = (unsigned long)sp; | 390 | a1 = (unsigned long)sp; |
379 | else | 391 | else |
380 | a1 = task->thread.sp; | 392 | a1 = (unsigned long)stack_pointer(task); |
381 | 393 | ||
382 | sp_start = a1 & ~(THREAD_SIZE-1); | 394 | sp_start = a1 & ~(THREAD_SIZE-1); |
383 | sp_end = sp_start + THREAD_SIZE; | 395 | sp_end = sp_start + THREAD_SIZE; |
@@ -420,7 +432,7 @@ void show_stack(struct task_struct *task, unsigned long *sp) | |||
420 | unsigned long *stack; | 432 | unsigned long *stack; |
421 | 433 | ||
422 | if (!sp) | 434 | if (!sp) |
423 | sp = (unsigned long *)task->thread.sp; | 435 | sp = stack_pointer(task); |
424 | stack = sp; | 436 | stack = sp; |
425 | 437 | ||
426 | printk("\nStack: "); | 438 | printk("\nStack: "); |