diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86_64/Kconfig.debug | 7 | ||||
-rw-r--r-- | arch/x86_64/kernel/irq.c | 28 |
2 files changed, 34 insertions, 1 deletions
diff --git a/arch/x86_64/Kconfig.debug b/arch/x86_64/Kconfig.debug index 0226f08be874..087a04868b25 100644 --- a/arch/x86_64/Kconfig.debug +++ b/arch/x86_64/Kconfig.debug | |||
@@ -35,6 +35,13 @@ config IOMMU_LEAK | |||
35 | Add a simple leak tracer to the IOMMU code. This is useful when you | 35 | Add a simple leak tracer to the IOMMU code. This is useful when you |
36 | are debugging a buggy device driver that leaks IOMMU mappings. | 36 | are debugging a buggy device driver that leaks IOMMU mappings. |
37 | 37 | ||
38 | config DEBUG_STACKOVERFLOW | ||
39 | bool "Check for stack overflows" | ||
40 | depends on DEBUG_KERNEL | ||
41 | help | ||
42 | This option will cause messages to be printed if free stack space | ||
43 | drops below a certain limit. | ||
44 | |||
38 | #config X86_REMOTE_DEBUG | 45 | #config X86_REMOTE_DEBUG |
39 | # bool "kgdb debugging stub" | 46 | # bool "kgdb debugging stub" |
40 | 47 | ||
diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c index 207ecdc39822..59518d4d4358 100644 --- a/arch/x86_64/kernel/irq.c +++ b/arch/x86_64/kernel/irq.c | |||
@@ -26,6 +26,30 @@ atomic_t irq_mis_count; | |||
26 | #endif | 26 | #endif |
27 | #endif | 27 | #endif |
28 | 28 | ||
29 | #ifdef CONFIG_DEBUG_STACKOVERFLOW | ||
30 | /* | ||
31 | * Probabilistic stack overflow check: | ||
32 | * | ||
33 | * Only check the stack in process context, because everything else | ||
34 | * runs on the big interrupt stacks. Checking reliably is too expensive, | ||
35 | * so we just check from interrupts. | ||
36 | */ | ||
37 | static inline void stack_overflow_check(struct pt_regs *regs) | ||
38 | { | ||
39 | u64 curbase = (u64) current->thread_info; | ||
40 | static unsigned long warned = -60*HZ; | ||
41 | |||
42 | if (regs->rsp >= curbase && regs->rsp <= curbase + THREAD_SIZE && | ||
43 | regs->rsp < curbase + sizeof(struct thread_info) + 128 && | ||
44 | time_after(jiffies, warned + 60*HZ)) { | ||
45 | printk("do_IRQ: %s near stack overflow (cur:%Lx,rsp:%lx)\n", | ||
46 | current->comm, curbase, regs->rsp); | ||
47 | show_stack(NULL,NULL); | ||
48 | warned = jiffies; | ||
49 | } | ||
50 | } | ||
51 | #endif | ||
52 | |||
29 | /* | 53 | /* |
30 | * Generic, controller-independent functions: | 54 | * Generic, controller-independent functions: |
31 | */ | 55 | */ |
@@ -96,7 +120,9 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs) | |||
96 | 120 | ||
97 | exit_idle(); | 121 | exit_idle(); |
98 | irq_enter(); | 122 | irq_enter(); |
99 | 123 | #ifdef CONFIG_DEBUG_STACKOVERFLOW | |
124 | stack_overflow_check(regs); | ||
125 | #endif | ||
100 | __do_IRQ(irq, regs); | 126 | __do_IRQ(irq, regs); |
101 | irq_exit(); | 127 | irq_exit(); |
102 | 128 | ||