From d153ea88dccf003173315b5d21acabebb897fb4a Mon Sep 17 00:00:00 2001
From: Paul Mundt <lethal@linux-sh.org>
Date: Wed, 27 Sep 2006 18:20:16 +0900
Subject: sh: stack debugging support.

This adds a DEBUG_STACK_USAGE and DEBUG_STACKOVERFLOW for SH.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
---
 arch/sh/Kconfig.debug        | 16 ++++++++++++++++
 arch/sh/kernel/head.S        |  4 +++-
 arch/sh/kernel/irq.c         | 17 ++++++++++++++++-
 arch/sh/kernel/vmlinux.lds.S | 14 ++++++++------
 4 files changed, 43 insertions(+), 8 deletions(-)

(limited to 'arch')

diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug
index 75ed1be8a49e..f0188e626be0 100644
--- a/arch/sh/Kconfig.debug
+++ b/arch/sh/Kconfig.debug
@@ -30,6 +30,22 @@ config EARLY_PRINTK
 	  when the kernel may crash or hang before the serial console is
 	  initialised. If unsure, say N.
 
+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 "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 and sysrq-P debug output.
+
+	  This option will slow down process creation somewhat.
+
 config KGDB
 	bool "Include KGDB kernel debugger"
 	select FRAME_POINTER
diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head.S
index c5e363872b91..3e7d00b7985a 100644
--- a/arch/sh/kernel/head.S
+++ b/arch/sh/kernel/head.S
@@ -11,6 +11,8 @@
  * Head.S contains the SH exception handlers and startup code.
  */
 #include <linux/linkage.h>
+#include <asm/thread_info.h>
+#include <asm/page.h>
 
 #ifdef CONFIG_CPU_SH4A
 #define SYNCO()		synco
@@ -95,7 +97,7 @@ ENTRY(_stext)
 
 	.balign 4
 1:	.long	0x400080F0		! MD=1, RB=0, BL=0, FD=1, IMASK=0xF
-2:	.long	init_thread_union+8192
+2:	.long	init_thread_union+THREAD_SIZE
 3:	.long	__bss_start
 4:	.long	_end
 5:	.long	start_kernel
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index c2e07f7f3496..7066611aeb72 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -60,7 +60,6 @@ unlock:
 }
 #endif
 
-
 asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
 		      unsigned long r6, unsigned long r7,
 		      struct pt_regs regs)
@@ -69,6 +68,22 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
 
 	irq_enter();
 
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+	/* Debugging check for stack overflow: is there less than 1KB free? */
+	{
+		long sp;
+
+		__asm__ __volatile__ ("and r15, %0" :
+					"=r" (sp) : "0" (THREAD_SIZE - 1));
+
+		if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
+			printk("do_IRQ: stack overflow: %ld\n",
+			       sp - sizeof(struct thread_info));
+			dump_stack();
+		}
+	}
+#endif
+
 #ifdef CONFIG_CPU_HAS_INTEVT
 	__asm__ __volatile__ (
 #ifdef CONFIG_CPU_HAS_SR_RB
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S
index eb860c51c697..0220d8a838a7 100644
--- a/arch/sh/kernel/vmlinux.lds.S
+++ b/arch/sh/kernel/vmlinux.lds.S
@@ -2,6 +2,8 @@
  * ld script to make SuperH Linux kernel
  * Written by Niibe Yutaka
  */
+#include <asm/thread_info.h>
+#include <asm/page.h>
 #include <asm-generic/vmlinux.lds.h>
 
 #ifdef CONFIG_CPU_LITTLE_ENDIAN
@@ -40,16 +42,16 @@ SECTIONS
 	*(.data)
 
  	 /* Align the initial ramdisk image (INITRD) on page boundaries. */
- 	 . = ALIGN(4096);
+ 	 . = ALIGN(PAGE_SIZE);
  	 __rd_start = .;
  	 *(.initrd)
- 	 . = ALIGN(4096);
+ 	 . = ALIGN(PAGE_SIZE);
  	 __rd_end = .;
 
 	CONSTRUCTORS
 	}
 
-  . = ALIGN(4096);
+  . = ALIGN(PAGE_SIZE);
   .data.page_aligned : { *(.data.idt) }
 
   . = ALIGN(32);
@@ -60,10 +62,10 @@ SECTIONS
 
   _edata = .;			/* End of data section */
 
-  . = ALIGN(8192);		/* init_task */
+  . = ALIGN(THREAD_SIZE);		/* init_task */
   .data.init_task : { *(.data.init_task) }
 
-  . = ALIGN(4096);		/* Init code and data */
+  . = ALIGN(PAGE_SIZE);		/* Init code and data */
   __init_begin = .;
   _sinittext = .;
   .init.text : { *(.init.text) }
@@ -94,7 +96,7 @@ SECTIONS
   __machvec_start = .;
   .init.machvec : { *(.init.machvec) }
   __machvec_end = .;
-  . = ALIGN(4096);
+  . = ALIGN(PAGE_SIZE);
   __init_end = .;
 
   . = ALIGN(4);
-- 
cgit v1.2.3