71 lines
1.8 KiB
Diff
71 lines
1.8 KiB
Diff
|
From: Matt Redfearn <matt.redfearn@imgtec.com>
|
||
|
Date: Mon, 19 Dec 2016 14:20:56 +0000
|
||
|
Subject: [PATCH] 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>
|
||
|
---
|
||
|
|
||
|
--- a/arch/mips/include/asm/irq.h
|
||
|
+++ b/arch/mips/include/asm/irq.h
|
||
|
@@ -17,6 +17,18 @@
|
||
|
|
||
|
#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
|
||
|
static inline int irq_canonicalize(int irq)
|
||
|
{
|
||
|
--- a/arch/mips/kernel/asm-offsets.c
|
||
|
+++ b/arch/mips/kernel/asm-offsets.c
|
||
|
@@ -101,6 +101,7 @@ void output_thread_info_defines(void)
|
||
|
OFFSET(TI_REGS, thread_info, regs);
|
||
|
DEFINE(_THREAD_SIZE, THREAD_SIZE);
|
||
|
DEFINE(_THREAD_MASK, THREAD_MASK);
|
||
|
+ DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE);
|
||
|
BLANK();
|
||
|
}
|
||
|
|
||
|
--- a/arch/mips/kernel/irq.c
|
||
|
+++ b/arch/mips/kernel/irq.c
|
||
|
@@ -25,6 +25,8 @@
|
||
|
#include <linux/atomic.h>
|
||
|
#include <asm/uaccess.h>
|
||
|
|
||
|
+void *irq_stack[NR_CPUS];
|
||
|
+
|
||
|
/*
|
||
|
* 'what should we do if we get a hw irq event on an illegal vector'.
|
||
|
* each architecture has to answer this themselves.
|
||
|
@@ -55,6 +57,15 @@ void __init init_IRQ(void)
|
||
|
irq_set_noprobe(i);
|
||
|
|
||
|
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
|