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>
This commit is contained in:
parent
ae2f5e5ed0
commit
fe8bd18ffe
|
@ -17,6 +17,18 @@
|
||||||
|
|
||||||
#include <irq.h>
|
#include <irq.h>
|
||||||
|
|
||||||
|
#define IRQ_STACK_SIZE THREAD_SIZE
|
||||||
|
|
||||||
|
extern void *irq_stack[NR_CPUS];
|
||||||
|
|
||||||
|
static inline bool on_irq_stack(int cpu, unsigned long sp)
|
||||||
|
{
|
||||||
|
unsigned long low = (unsigned long)irq_stack[cpu];
|
||||||
|
unsigned long high = low + IRQ_STACK_SIZE;
|
||||||
|
|
||||||
|
return (low <= sp && sp <= high);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_I8259
|
#ifdef CONFIG_I8259
|
||||||
static inline int irq_canonicalize(int irq)
|
static inline int irq_canonicalize(int irq)
|
||||||
{
|
{
|
||||||
|
|
|
@ -102,6 +102,7 @@ void output_thread_info_defines(void)
|
||||||
OFFSET(TI_REGS, thread_info, regs);
|
OFFSET(TI_REGS, thread_info, regs);
|
||||||
DEFINE(_THREAD_SIZE, THREAD_SIZE);
|
DEFINE(_THREAD_SIZE, THREAD_SIZE);
|
||||||
DEFINE(_THREAD_MASK, THREAD_MASK);
|
DEFINE(_THREAD_MASK, THREAD_MASK);
|
||||||
|
DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE);
|
||||||
BLANK();
|
BLANK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include <linux/atomic.h>
|
#include <linux/atomic.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
|
|
||||||
|
void *irq_stack[NR_CPUS];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 'what should we do if we get a hw irq event on an illegal vector'.
|
* 'what should we do if we get a hw irq event on an illegal vector'.
|
||||||
* each architecture has to answer this themselves.
|
* each architecture has to answer this themselves.
|
||||||
|
@ -58,6 +60,15 @@ void __init init_IRQ(void)
|
||||||
clear_c0_status(ST0_IM);
|
clear_c0_status(ST0_IM);
|
||||||
|
|
||||||
arch_init_irq();
|
arch_init_irq();
|
||||||
|
|
||||||
|
for_each_possible_cpu(i) {
|
||||||
|
int irq_pages = IRQ_STACK_SIZE / PAGE_SIZE;
|
||||||
|
void *s = (void *)__get_free_pages(GFP_KERNEL, irq_pages);
|
||||||
|
|
||||||
|
irq_stack[i] = s;
|
||||||
|
pr_debug("CPU%d IRQ stack at 0x%p - 0x%p\n", i,
|
||||||
|
irq_stack[i], irq_stack[i] + IRQ_STACK_SIZE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_STACKOVERFLOW
|
#ifdef CONFIG_DEBUG_STACKOVERFLOW
|
||||||
|
|
Loading…
Reference in New Issue