diff options
author | From: jiang.adam@gmail.com <From: jiang.adam@gmail.com> | 2010-08-27 05:32:06 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2010-10-29 14:08:27 -0400 |
commit | 334c86c494b9a5754d4c0ffa3110b18c9771013b (patch) | |
tree | ab0ceed9ff00fd7a0b7bbd194b537f8d1a271aef /arch | |
parent | b78807158be93c4756f88b5fc0790863f2690fdc (diff) |
MIPS: IRQ: Add stackoverflow detection
Add stackoverflow detection to mips arch
Signed-off-by: Adam Jiang <jiang.adam@gmail.com>
Cc: dmitri.vorobiev@movial.com
Cc: wuzhangjin@gmail.com
Cc: ddaney@caviumnetworks.com
Cc: peterz@infradead.org
Cc: fweisbec@gmail.com
Cc: tj@kernel.org
Cc: tglx@linutronix.de
Cc: mingo@elte.hu
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/1559/
Patchwork: https://patchwork.linux-mips.org/patch/1651/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips/Kconfig.debug | 9 | ||||
-rw-r--r-- | arch/mips/include/asm/thread_info.h | 2 | ||||
-rw-r--r-- | arch/mips/kernel/irq.c | 24 |
3 files changed, 35 insertions, 0 deletions
diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug index 43dc27997730..f437cd1fafb8 100644 --- a/arch/mips/Kconfig.debug +++ b/arch/mips/Kconfig.debug | |||
@@ -67,6 +67,15 @@ config CMDLINE_OVERRIDE | |||
67 | 67 | ||
68 | Normally, you will choose 'N' here. | 68 | Normally, you will choose 'N' here. |
69 | 69 | ||
70 | config DEBUG_STACKOVERFLOW | ||
71 | bool "Check for stack overflows" | ||
72 | depends on DEBUG_KERNEL | ||
73 | help | ||
74 | This option will cause messages to be printed if free stack space | ||
75 | drops below a certain limit(2GB on MIPS). The debugging option | ||
76 | provides another way to check stack overflow happened on kernel mode | ||
77 | stack usually caused by nested interruption. | ||
78 | |||
70 | config DEBUG_STACK_USAGE | 79 | config DEBUG_STACK_USAGE |
71 | bool "Enable stack utilization instrumentation" | 80 | bool "Enable stack utilization instrumentation" |
72 | depends on DEBUG_KERNEL | 81 | depends on DEBUG_KERNEL |
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index 70df9c0d3c5b..d309556cacf8 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h | |||
@@ -83,6 +83,8 @@ register struct thread_info *__current_thread_info __asm__("$28"); | |||
83 | #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) | 83 | #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) |
84 | #define THREAD_MASK (THREAD_SIZE - 1UL) | 84 | #define THREAD_MASK (THREAD_SIZE - 1UL) |
85 | 85 | ||
86 | #define STACK_WARN (THREAD_SIZE / 8) | ||
87 | |||
86 | #define __HAVE_ARCH_THREAD_INFO_ALLOCATOR | 88 | #define __HAVE_ARCH_THREAD_INFO_ALLOCATOR |
87 | 89 | ||
88 | #ifdef CONFIG_DEBUG_STACK_USAGE | 90 | #ifdef CONFIG_DEBUG_STACK_USAGE |
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(); |