]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
arm64: unwind: avoid percpu indirection for irq stack
authorMark Rutland <mark.rutland@arm.com>
Thu, 20 Jul 2017 13:01:01 +0000 (14:01 +0100)
committerKleber Sacilotto de Souza <kleber.souza@canonical.com>
Wed, 7 Mar 2018 11:07:05 +0000 (12:07 +0100)
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: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Ard 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>
(cherry picked from commit 096683724cb2eb95fea759a2580996df1039fdd0)

CVE-2017-5753
CVE-2017-5715
CVE-2017-5754

Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
Acked-by: Brad Figg <brad.figg@canonical.com>
Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
Acked-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
arch/arm64/include/asm/irq.h
arch/arm64/kernel/ptrace.c
arch/arm64/kernel/stacktrace.c
arch/arm64/kernel/traps.c

index b77197d941fc442c4bad04b185d5cf786ca9fea5..6d6f85e4923e6e69299c6ac85495886db4014bb6 100644 (file)
@@ -32,7 +32,7 @@ DECLARE_PER_CPU(unsigned long [IRQ_STACK_SIZE/sizeof(long)], irq_stack);
  * 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
@@ -47,10 +47,10 @@ static inline int nr_legacy_irqs(void)
        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 */
-       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;
 
        return (low <= sp && sp <= high);
index 1b38c0150aec6f034289b5e1faead0727f8f5056..baf0838205c761f3ed7253d0abcb138df98f869c 100644 (file)
@@ -127,7 +127,7 @@ static bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr)
 {
        return ((addr & ~(THREAD_SIZE - 1))  ==
                (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1))) ||
-               on_irq_stack(addr, raw_smp_processor_id());
+               on_irq_stack(addr);
 }
 
 /**
index 09d37d66b6301abee1852bb0aead091fa1157098..6ffb965be64112921f1997de3b811f9643b1b564 100644 (file)
@@ -54,13 +54,13 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
         * non-preemptible context.
         */
        if (tsk == current && !preemptible())
-               irq_stack_ptr = IRQ_STACK_PTR(smp_processor_id());
+               irq_stack_ptr = IRQ_STACK_PTR();
        else
                irq_stack_ptr = 0;
 
        low  = frame->sp;
        /* 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;
        else
                high = ALIGN(low, THREAD_SIZE) - 0x20;
index c99ffd8dce274adad6ac00bdb7f0da3758b86965..81c10020a018f0e4996502825c9f108ca90b03d2 100644 (file)
@@ -159,7 +159,7 @@ void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
         * non-preemptible context.
         */
        if (tsk == current && !preemptible())
-               irq_stack_ptr = IRQ_STACK_PTR(smp_processor_id());
+               irq_stack_ptr = IRQ_STACK_PTR();
        else
                irq_stack_ptr = 0;