diff options
author | Yang Shi <yang.shi@linaro.org> | 2016-02-11 16:53:10 -0500 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2016-02-12 10:53:51 -0500 |
commit | a80a0eb70c358f8c7dda4bb62b2278dc6285217b (patch) | |
tree | a0fda0517271586316fbd476aed280734a245151 /arch/arm64/kernel/traps.c | |
parent | e04a28d45ff343b47a4ffc4dee3a3e279e76ddfa (diff) |
arm64: make irq_stack_ptr more robust
Switching between stacks is only valid if we are tracing ourselves while on the
irq_stack, so it is only valid when in current and non-preemptible context,
otherwise is is just zeroed off.
Fixes: 132cd887b5c5 ("arm64: Modify stack trace and dump for use with irq_stack")
Acked-by: James Morse <james.morse@arm.com>
Tested-by: James Morse <james.morse@arm.com>
Signed-off-by: Yang Shi <yang.shi@linaro.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm64/kernel/traps.c')
-rw-r--r-- | arch/arm64/kernel/traps.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index cbedd724f48e..c5392081b49b 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c | |||
@@ -146,9 +146,18 @@ static void dump_instr(const char *lvl, struct pt_regs *regs) | |||
146 | static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) | 146 | static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) |
147 | { | 147 | { |
148 | struct stackframe frame; | 148 | struct stackframe frame; |
149 | unsigned long irq_stack_ptr = IRQ_STACK_PTR(smp_processor_id()); | 149 | unsigned long irq_stack_ptr; |
150 | int skip; | 150 | int skip; |
151 | 151 | ||
152 | /* | ||
153 | * Switching between stacks is valid when tracing current and in | ||
154 | * non-preemptible context. | ||
155 | */ | ||
156 | if (tsk == current && !preemptible()) | ||
157 | irq_stack_ptr = IRQ_STACK_PTR(smp_processor_id()); | ||
158 | else | ||
159 | irq_stack_ptr = 0; | ||
160 | |||
152 | pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); | 161 | pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk); |
153 | 162 | ||
154 | if (!tsk) | 163 | if (!tsk) |