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(); |
