arm64: Modify stack trace and dump for use with irq_stack
This patch allows unwind_frame() to traverse from interrupt stack to task stack correctly. It requires data from a dummy stack frame, created during irq_stack_entry(), added by a later patch. A similar approach is taken to modify dump_backtrace(), which expects to find struct pt_regs underneath any call to functions marked __exception. When on an irq_stack, the struct pt_regs is stored on the old task stack, the location of which is stored in the dummy stack frame. Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> [james.morse: merged two patches, reworked for per_cpu irq_stacks, and no alignment guarantees, added irq_stack definitions] Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
This commit is contained in:

committed by
Will Deacon

parent
6cdf9c7ca6
commit
132cd887b5
@@ -146,6 +146,7 @@ static void dump_instr(const char *lvl, struct pt_regs *regs)
|
||||
static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
|
||||
{
|
||||
struct stackframe frame;
|
||||
unsigned long irq_stack_ptr = IRQ_STACK_PTR(smp_processor_id());
|
||||
|
||||
pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
|
||||
|
||||
@@ -180,9 +181,20 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
|
||||
if (ret < 0)
|
||||
break;
|
||||
stack = frame.sp;
|
||||
if (in_exception_text(where))
|
||||
if (in_exception_text(where)) {
|
||||
/*
|
||||
* If we switched to the irq_stack before calling this
|
||||
* exception handler, then the pt_regs will be on the
|
||||
* task stack. The easiest way to tell is if the large
|
||||
* pt_regs would overlap with the end of the irq_stack.
|
||||
*/
|
||||
if (stack < irq_stack_ptr &&
|
||||
(stack + sizeof(struct pt_regs)) > irq_stack_ptr)
|
||||
stack = IRQ_STACK_TO_TASK_STACK(irq_stack_ptr);
|
||||
|
||||
dump_mem("", "Exception stack", stack,
|
||||
stack + sizeof(struct pt_regs), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user