Skip to content

Commit 334c86c

Browse files
From: jiang.adam@gmail.comralfbaechle
authored andcommitted
MIPS: IRQ: Add stackoverflow detection
Add stackoverflow detection to mips arch Signed-off-by: Adam Jiang <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] Patchwork: https://patchwork.linux-mips.org/patch/1559/ Patchwork: https://patchwork.linux-mips.org/patch/1651/ Signed-off-by: Ralf Baechle <[email protected]>
1 parent b788071 commit 334c86c

File tree

3 files changed

+35
-0
lines changed

3 files changed

+35
-0
lines changed

arch/mips/Kconfig.debug

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,15 @@ config CMDLINE_OVERRIDE
6767

6868
Normally, you will choose 'N' here.
6969

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+
7079
config DEBUG_STACK_USAGE
7180
bool "Enable stack utilization instrumentation"
7281
depends on DEBUG_KERNEL

arch/mips/include/asm/thread_info.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ register struct thread_info *__current_thread_info __asm__("$28");
8383
#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
8484
#define THREAD_MASK (THREAD_SIZE - 1UL)
8585

86+
#define STACK_WARN (THREAD_SIZE / 8)
87+
8688
#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
8789

8890
#ifdef CONFIG_DEBUG_STACK_USAGE

arch/mips/kernel/irq.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,29 @@ void __init init_IRQ(void)
151151
#endif
152152
}
153153

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+
154177
/*
155178
* do_IRQ handles all normal device IRQ's (the special
156179
* SMP cross-CPU interrupts have their own specific
@@ -159,6 +182,7 @@ void __init init_IRQ(void)
159182
void __irq_entry do_IRQ(unsigned int irq)
160183
{
161184
irq_enter();
185+
check_stack_overflow();
162186
__DO_IRQ_SMTC_HOOK(irq);
163187
generic_handle_irq(irq);
164188
irq_exit();

0 commit comments

Comments
 (0)