diff options
Diffstat (limited to 'arch/mips/kernel/irq.c')
-rw-r--r-- | arch/mips/kernel/irq.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index c6345f579a8a..4f93db58a79e 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c | |||
@@ -151,6 +151,29 @@ void __init init_IRQ(void) | |||
151 | #endif | 151 | #endif |
152 | } | 152 | } |
153 | 153 | ||
154 | #ifdef DEBUG_STACKOVERFLOW | ||
155 | static inline void check_stack_overflow(void) | ||
156 | { | ||
157 | unsigned long sp; | ||
158 | |||
159 | __asm__ __volatile__("move %0, $sp" : "=r" (sp)); | ||
160 | sp &= THREAD_MASK; | ||
161 | |||
162 | /* | ||
163 | * Check for stack overflow: is there less than STACK_WARN free? | ||
164 | * STACK_WARN is defined as 1/8 of THREAD_SIZE by default. | ||
165 | */ | ||
166 | if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) { | ||
167 | printk("do_IRQ: stack overflow: %ld\n", | ||
168 | sp - sizeof(struct thread_info)); | ||
169 | dump_stack(); | ||
170 | } | ||
171 | } | ||
172 | #else | ||
173 | static inline void check_stack_overflow(void) {} | ||
174 | #endif | ||
175 | |||
176 | |||
154 | /* | 177 | /* |
155 | * do_IRQ handles all normal device IRQ's (the special | 178 | * do_IRQ handles all normal device IRQ's (the special |
156 | * SMP cross-CPU interrupts have their own specific | 179 | * SMP cross-CPU interrupts have their own specific |
@@ -159,6 +182,7 @@ void __init init_IRQ(void) | |||
159 | void __irq_entry do_IRQ(unsigned int irq) | 182 | void __irq_entry do_IRQ(unsigned int irq) |
160 | { | 183 | { |
161 | irq_enter(); | 184 | irq_enter(); |
185 | check_stack_overflow(); | ||
162 | __DO_IRQ_SMTC_HOOK(irq); | 186 | __DO_IRQ_SMTC_HOOK(irq); |
163 | generic_handle_irq(irq); | 187 | generic_handle_irq(irq); |
164 | irq_exit(); | 188 | irq_exit(); |