aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/blackfin/Kconfig.debug16
-rw-r--r--arch/blackfin/include/asm/processor.h8
-rw-r--r--arch/blackfin/include/asm/thread_info.h1
-rw-r--r--arch/blackfin/kernel/irqchip.c16
4 files changed, 40 insertions, 1 deletions
diff --git a/arch/blackfin/Kconfig.debug b/arch/blackfin/Kconfig.debug
index 3ad25983ec9..bfd712ab125 100644
--- a/arch/blackfin/Kconfig.debug
+++ b/arch/blackfin/Kconfig.debug
@@ -2,6 +2,22 @@ menu "Kernel hacking"
source "lib/Kconfig.debug"
+config DEBUG_STACKOVERFLOW
+ bool "Check for stack overflows"
+ depends on DEBUG_KERNEL
+ help
+ This option will cause messages to be printed if free stack space
+ drops below a certain limit.
+
+config DEBUG_STACK_USAGE
+ bool "Enable stack utilization instrumentation"
+ depends on DEBUG_KERNEL
+ help
+ Enables the display of the minimum amount of free stack which each
+ task has ever had available in the sysrq-T output.
+
+ This option will slow down process creation somewhat.
+
config HAVE_ARCH_KGDB
def_bool y
diff --git a/arch/blackfin/include/asm/processor.h b/arch/blackfin/include/asm/processor.h
index 2cb0b8711fa..83d57a85b14 100644
--- a/arch/blackfin/include/asm/processor.h
+++ b/arch/blackfin/include/asm/processor.h
@@ -24,6 +24,14 @@ static inline void wrusp(unsigned long usp)
__asm__ __volatile__("usp = %0;\n\t"::"da"(usp));
}
+static inline unsigned long __get_SP(void)
+{
+ unsigned long sp;
+
+ __asm__ __volatile__("%0 = sp;\n\t" : "=da"(sp));
+ return sp;
+}
+
/*
* User space process size: 1st byte beyond user address space.
* Fairly meaningless on nommu. Parts of user programs can be scattered
diff --git a/arch/blackfin/include/asm/thread_info.h b/arch/blackfin/include/asm/thread_info.h
index 642769329d1..1d380def241 100644
--- a/arch/blackfin/include/asm/thread_info.h
+++ b/arch/blackfin/include/asm/thread_info.h
@@ -44,6 +44,7 @@
*/
#define THREAD_SIZE_ORDER 1
#define THREAD_SIZE 8192 /* 2 pages */
+#define STACK_WARN (THREAD_SIZE/8)
#ifndef __ASSEMBLY__
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
index 5ad07525ea3..1624e112968 100644
--- a/arch/blackfin/kernel/irqchip.c
+++ b/arch/blackfin/kernel/irqchip.c
@@ -120,7 +120,21 @@ asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
desc = &bad_irq_desc;
irq_enter();
-
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+ /* Debugging check for stack overflow: is there less than STACK_WARN free? */
+ {
+ long sp;
+
+ sp = __get_SP() & (THREAD_SIZE-1);
+
+ if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
+ dump_stack();
+ printk(KERN_EMERG "%s: possible stack overflow while handling irq %i "
+ " only %ld bytes free\n",
+ __func__, irq, sp - sizeof(struct thread_info));
+ }
+ }
+#endif
generic_handle_irq(irq);
/* If we're the only interrupt running (ignoring IRQ15 which is for