aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Redfearn <matt.redfearn@imgtec.com>2016-12-19 09:20:56 -0500
committerRalf Baechle <ralf@linux-mips.org>2017-01-03 10:34:34 -0500
commitfe8bd18ffea5327344d4ec2bf11f47951212abd0 (patch)
tree928a7f758616975d5cc5b66512aa24939c3e9e3f
parentae2f5e5ed04a17c1aa1f0a3714c725e12c21d2a9 (diff)
MIPS: Introduce irq_stack
Allocate a per-cpu irq stack for use within interrupt handlers. Also add a utility function on_irq_stack to determine if a given stack pointer is within the irq stack for that cpu. Signed-off-by: Matt Redfearn <matt.redfearn@imgtec.com> Acked-by: Jason A. Donenfeld <jason@zx2c4.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Chris Metcalf <cmetcalf@mellanox.com> Cc: Petr Mladek <pmladek@suse.com> Cc: James Hogan <james.hogan@imgtec.com> Cc: Paul Burton <paul.burton@imgtec.com> Cc: Aaron Tomlin <atomlin@redhat.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: linux-kernel@vger.kernel.org Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/14740/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/include/asm/irq.h12
-rw-r--r--arch/mips/kernel/asm-offsets.c1
-rw-r--r--arch/mips/kernel/irq.c11
3 files changed, 24 insertions, 0 deletions
diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h
index 6bf10e796553..956db6e201d1 100644
--- a/arch/mips/include/asm/irq.h
+++ b/arch/mips/include/asm/irq.h
@@ -17,6 +17,18 @@
17 17
18#include <irq.h> 18#include <irq.h>
19 19
20#define IRQ_STACK_SIZE THREAD_SIZE
21
22extern void *irq_stack[NR_CPUS];
23
24static inline bool on_irq_stack(int cpu, unsigned long sp)
25{
26 unsigned long low = (unsigned long)irq_stack[cpu];
27 unsigned long high = low + IRQ_STACK_SIZE;
28
29 return (low <= sp && sp <= high);
30}
31
20#ifdef CONFIG_I8259 32#ifdef CONFIG_I8259
21static inline int irq_canonicalize(int irq) 33static inline int irq_canonicalize(int irq)
22{ 34{
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index 6080582a26d1..a7277698d328 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -102,6 +102,7 @@ void output_thread_info_defines(void)
102 OFFSET(TI_REGS, thread_info, regs); 102 OFFSET(TI_REGS, thread_info, regs);
103 DEFINE(_THREAD_SIZE, THREAD_SIZE); 103 DEFINE(_THREAD_SIZE, THREAD_SIZE);
104 DEFINE(_THREAD_MASK, THREAD_MASK); 104 DEFINE(_THREAD_MASK, THREAD_MASK);
105 DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE);
105 BLANK(); 106 BLANK();
106} 107}
107 108
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index f8f5836eb3c1..ba150c755fcc 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -25,6 +25,8 @@
25#include <linux/atomic.h> 25#include <linux/atomic.h>
26#include <linux/uaccess.h> 26#include <linux/uaccess.h>
27 27
28void *irq_stack[NR_CPUS];
29
28/* 30/*
29 * 'what should we do if we get a hw irq event on an illegal vector'. 31 * 'what should we do if we get a hw irq event on an illegal vector'.
30 * each architecture has to answer this themselves. 32 * each architecture has to answer this themselves.
@@ -58,6 +60,15 @@ void __init init_IRQ(void)
58 clear_c0_status(ST0_IM); 60 clear_c0_status(ST0_IM);
59 61
60 arch_init_irq(); 62 arch_init_irq();
63
64 for_each_possible_cpu(i) {
65 int irq_pages = IRQ_STACK_SIZE / PAGE_SIZE;
66 void *s = (void *)__get_free_pages(GFP_KERNEL, irq_pages);
67
68 irq_stack[i] = s;
69 pr_debug("CPU%d IRQ stack at 0x%p - 0x%p\n", i,
70 irq_stack[i], irq_stack[i] + IRQ_STACK_SIZE);
71 }
61} 72}
62 73
63#ifdef CONFIG_DEBUG_STACKOVERFLOW 74#ifdef CONFIG_DEBUG_STACKOVERFLOW