Commit 09668372 authored by Mark Rutland's avatar Mark Rutland

arm64: unwind: avoid percpu indirection for irq stack

Our IRQ_STACK_PTR() and on_irq_stack() helpers both take a cpu argument,
used to generate a percpu address. In all cases, they are passed
{raw_,}smp_processor_id(), so this parameter is redundant.

Since {raw_,}smp_processor_id() use a percpu variable internally, this
approach means we generate a percpu offset to find the current cpu, then
use this to index an array of percpu offsets, which we then use to find
the current CPU's IRQ stack pointer. Thus, most of the work is
redundant.

Instead, we can consistently use raw_cpu_ptr() to generate the CPU's
irq_stack pointer by simply adding the percpu offset to the irq_stack
address, which is simpler in both respects.
Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
Signed-off-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
parent ed84b4e9
...@@ -32,7 +32,7 @@ DECLARE_PER_CPU(unsigned long [IRQ_STACK_SIZE/sizeof(long)], irq_stack); ...@@ -32,7 +32,7 @@ DECLARE_PER_CPU(unsigned long [IRQ_STACK_SIZE/sizeof(long)], irq_stack);
* from kernel_entry can be found. * from kernel_entry can be found.
* *
*/ */
#define IRQ_STACK_PTR(cpu) ((unsigned long)per_cpu(irq_stack, cpu) + IRQ_STACK_START_SP) #define IRQ_STACK_PTR() ((unsigned long)raw_cpu_ptr(irq_stack) + IRQ_STACK_START_SP)
/* /*
* The offset from irq_stack_ptr where entry.S will store the original * The offset from irq_stack_ptr where entry.S will store the original
...@@ -47,10 +47,10 @@ static inline int nr_legacy_irqs(void) ...@@ -47,10 +47,10 @@ static inline int nr_legacy_irqs(void)
return 0; return 0;
} }
static inline bool on_irq_stack(unsigned long sp, int cpu) static inline bool on_irq_stack(unsigned long sp)
{ {
/* variable names the same as kernel/stacktrace.c */ /* variable names the same as kernel/stacktrace.c */
unsigned long low = (unsigned long)per_cpu(irq_stack, cpu); unsigned long low = (unsigned long)raw_cpu_ptr(irq_stack);
unsigned long high = low + IRQ_STACK_START_SP; unsigned long high = low + IRQ_STACK_START_SP;
return (low <= sp && sp <= high); return (low <= sp && sp <= high);
......
...@@ -127,7 +127,7 @@ static bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr) ...@@ -127,7 +127,7 @@ static bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr)
{ {
return ((addr & ~(THREAD_SIZE - 1)) == return ((addr & ~(THREAD_SIZE - 1)) ==
(kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1))) || (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1))) ||
on_irq_stack(addr, raw_smp_processor_id()); on_irq_stack(addr);
} }
/** /**
......
...@@ -54,13 +54,13 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame) ...@@ -54,13 +54,13 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
* non-preemptible context. * non-preemptible context.
*/ */
if (tsk == current && !preemptible()) if (tsk == current && !preemptible())
irq_stack_ptr = IRQ_STACK_PTR(smp_processor_id()); irq_stack_ptr = IRQ_STACK_PTR();
else else
irq_stack_ptr = 0; irq_stack_ptr = 0;
low = frame->sp; low = frame->sp;
/* irq stacks are not THREAD_SIZE aligned */ /* irq stacks are not THREAD_SIZE aligned */
if (on_irq_stack(frame->sp, raw_smp_processor_id())) if (on_irq_stack(frame->sp))
high = irq_stack_ptr; high = irq_stack_ptr;
else else
high = ALIGN(low, THREAD_SIZE) - 0x20; high = ALIGN(low, THREAD_SIZE) - 0x20;
......
...@@ -159,7 +159,7 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk) ...@@ -159,7 +159,7 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
* non-preemptible context. * non-preemptible context.
*/ */
if (tsk == current && !preemptible()) if (tsk == current && !preemptible())
irq_stack_ptr = IRQ_STACK_PTR(smp_processor_id()); irq_stack_ptr = IRQ_STACK_PTR();
else else
irq_stack_ptr = 0; irq_stack_ptr = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment