diff options
-rw-r--r-- | arch/arm64/kernel/stacktrace.c | 13 | ||||
-rw-r--r-- | arch/arm64/kernel/traps.c | 11 |
2 files changed, 16 insertions, 8 deletions
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c index 12a18cbc4295..d9751a4769e7 100644 --- a/arch/arm64/kernel/stacktrace.c +++ b/arch/arm64/kernel/stacktrace.c | |||
@@ -44,14 +44,13 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) | |||
44 | unsigned long irq_stack_ptr; | 44 | unsigned long irq_stack_ptr; |
45 | 45 | ||
46 | /* | 46 | /* |
47 | * Use raw_smp_processor_id() to avoid false-positives from | 47 | * Switching between stacks is valid when tracing current and in |
48 | * CONFIG_DEBUG_PREEMPT. get_wchan() calls unwind_frame() on sleeping | 48 | * non-preemptible context. |
49 | * task stacks, we can be pre-empted in this case, so | ||
50 | * {raw_,}smp_processor_id() may give us the wrong value. Sleeping | ||
51 | * tasks can't ever be on an interrupt stack, so regardless of cpu, | ||
52 | * the checks will always fail. | ||
53 | */ | 49 | */ |
54 | irq_stack_ptr = IRQ_STACK_PTR(raw_smp_processor_id()); | 50 | if (tsk == current && !preemptible()) |
51 | irq_stack_ptr = IRQ_STACK_PTR(smp_processor_id()); | ||
52 | else | ||
53 | irq_stack_ptr = 0; | ||
55 | 54 | ||
56 | low = frame->sp; | 55 | low = frame->sp; |
57 | /* irq stacks are not THREAD_SIZE aligned */ | 56 | /* irq stacks are not THREAD_SIZE aligned */ |
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) |