aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2006-09-27 05:20:16 -0400
committerPaul Mundt <lethal@linux-sh.org>2006-09-27 05:20:16 -0400
commitd153ea88dccf003173315b5d21acabebb897fb4a (patch)
tree5cdc96ef0ec58026d82c03f76250ac1833f566d4
parent7a440c950efb5cdc8a05cc6c3ec8fc864b60ef77 (diff)
sh: stack debugging support.
This adds a DEBUG_STACK_USAGE and DEBUG_STACKOVERFLOW for SH. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r--arch/sh/Kconfig.debug16
-rw-r--r--arch/sh/kernel/head.S4
-rw-r--r--arch/sh/kernel/irq.c17
-rw-r--r--arch/sh/kernel/vmlinux.lds.S14
-rw-r--r--include/asm-sh/page.h2
-rw-r--r--include/asm-sh/thread_info.h12
6 files changed, 52 insertions, 13 deletions
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
30 when the kernel may crash or hang before the serial console is 30 when the kernel may crash or hang before the serial console is
31 initialised. If unsure, say N. 31 initialised. If unsure, say N.
32 32
33config DEBUG_STACKOVERFLOW
34 bool "Check for stack overflows"
35 depends on DEBUG_KERNEL
36 help
37 This option will cause messages to be printed if free stack space
38 drops below a certain limit.
39
40config DEBUG_STACK_USAGE
41 bool "Stack utilization instrumentation"
42 depends on DEBUG_KERNEL
43 help
44 Enables the display of the minimum amount of free stack which each
45 task has ever had available in the sysrq-T and sysrq-P debug output.
46
47 This option will slow down process creation somewhat.
48
33config KGDB 49config KGDB
34 bool "Include KGDB kernel debugger" 50 bool "Include KGDB kernel debugger"
35 select FRAME_POINTER 51 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 @@
11 * Head.S contains the SH exception handlers and startup code. 11 * Head.S contains the SH exception handlers and startup code.
12 */ 12 */
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14#include <asm/thread_info.h>
15#include <asm/page.h>
14 16
15#ifdef CONFIG_CPU_SH4A 17#ifdef CONFIG_CPU_SH4A
16#define SYNCO() synco 18#define SYNCO() synco
@@ -95,7 +97,7 @@ ENTRY(_stext)
95 97
96 .balign 4 98 .balign 4
971: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF 991: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF
982: .long init_thread_union+8192 1002: .long init_thread_union+THREAD_SIZE
993: .long __bss_start 1013: .long __bss_start
1004: .long _end 1024: .long _end
1015: .long start_kernel 1035: .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:
60} 60}
61#endif 61#endif
62 62
63
64asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, 63asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
65 unsigned long r6, unsigned long r7, 64 unsigned long r6, unsigned long r7,
66 struct pt_regs regs) 65 struct pt_regs regs)
@@ -69,6 +68,22 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
69 68
70 irq_enter(); 69 irq_enter();
71 70
71#ifdef CONFIG_DEBUG_STACKOVERFLOW
72 /* Debugging check for stack overflow: is there less than 1KB free? */
73 {
74 long sp;
75
76 __asm__ __volatile__ ("and r15, %0" :
77 "=r" (sp) : "0" (THREAD_SIZE - 1));
78
79 if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
80 printk("do_IRQ: stack overflow: %ld\n",
81 sp - sizeof(struct thread_info));
82 dump_stack();
83 }
84 }
85#endif
86
72#ifdef CONFIG_CPU_HAS_INTEVT 87#ifdef CONFIG_CPU_HAS_INTEVT
73 __asm__ __volatile__ ( 88 __asm__ __volatile__ (
74#ifdef CONFIG_CPU_HAS_SR_RB 89#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 @@
2 * ld script to make SuperH Linux kernel 2 * ld script to make SuperH Linux kernel
3 * Written by Niibe Yutaka 3 * Written by Niibe Yutaka
4 */ 4 */
5#include <asm/thread_info.h>
6#include <asm/page.h>
5#include <asm-generic/vmlinux.lds.h> 7#include <asm-generic/vmlinux.lds.h>
6 8
7#ifdef CONFIG_CPU_LITTLE_ENDIAN 9#ifdef CONFIG_CPU_LITTLE_ENDIAN
@@ -40,16 +42,16 @@ SECTIONS
40 *(.data) 42 *(.data)
41 43
42 /* Align the initial ramdisk image (INITRD) on page boundaries. */ 44 /* Align the initial ramdisk image (INITRD) on page boundaries. */
43 . = ALIGN(4096); 45 . = ALIGN(PAGE_SIZE);
44 __rd_start = .; 46 __rd_start = .;
45 *(.initrd) 47 *(.initrd)
46 . = ALIGN(4096); 48 . = ALIGN(PAGE_SIZE);
47 __rd_end = .; 49 __rd_end = .;
48 50
49 CONSTRUCTORS 51 CONSTRUCTORS
50 } 52 }
51 53
52 . = ALIGN(4096); 54 . = ALIGN(PAGE_SIZE);
53 .data.page_aligned : { *(.data.idt) } 55 .data.page_aligned : { *(.data.idt) }
54 56
55 . = ALIGN(32); 57 . = ALIGN(32);
@@ -60,10 +62,10 @@ SECTIONS
60 62
61 _edata = .; /* End of data section */ 63 _edata = .; /* End of data section */
62 64
63 . = ALIGN(8192); /* init_task */ 65 . = ALIGN(THREAD_SIZE); /* init_task */
64 .data.init_task : { *(.data.init_task) } 66 .data.init_task : { *(.data.init_task) }
65 67
66 . = ALIGN(4096); /* Init code and data */ 68 . = ALIGN(PAGE_SIZE); /* Init code and data */
67 __init_begin = .; 69 __init_begin = .;
68 _sinittext = .; 70 _sinittext = .;
69 .init.text : { *(.init.text) } 71 .init.text : { *(.init.text) }
@@ -94,7 +96,7 @@ SECTIONS
94 __machvec_start = .; 96 __machvec_start = .;
95 .init.machvec : { *(.init.machvec) } 97 .init.machvec : { *(.init.machvec) }
96 __machvec_end = .; 98 __machvec_end = .;
97 . = ALIGN(4096); 99 . = ALIGN(PAGE_SIZE);
98 __init_end = .; 100 __init_end = .;
99 101
100 . = ALIGN(4); 102 . = ALIGN(4);
diff --git a/include/asm-sh/page.h b/include/asm-sh/page.h
index e9135532d00c..888d6fe0030e 100644
--- a/include/asm-sh/page.h
+++ b/include/asm-sh/page.h
@@ -16,7 +16,7 @@
16 16
17/* PAGE_SHIFT determines the page size */ 17/* PAGE_SHIFT determines the page size */
18#define PAGE_SHIFT 12 18#define PAGE_SHIFT 12
19#define PAGE_SIZE (1UL << PAGE_SHIFT) 19#define PAGE_SIZE (1 << PAGE_SHIFT)
20#define PAGE_MASK (~(PAGE_SIZE-1)) 20#define PAGE_MASK (~(PAGE_SIZE-1))
21#define PTE_MASK PAGE_MASK 21#define PTE_MASK PAGE_MASK
22 22
diff --git a/include/asm-sh/thread_info.h b/include/asm-sh/thread_info.h
index 5eb874b065a6..605259f88113 100644
--- a/include/asm-sh/thread_info.h
+++ b/include/asm-sh/thread_info.h
@@ -29,6 +29,8 @@ struct thread_info {
29#endif 29#endif
30 30
31#define PREEMPT_ACTIVE 0x10000000 31#define PREEMPT_ACTIVE 0x10000000
32#define THREAD_SIZE (PAGE_SIZE * 2)
33#define STACK_WARN (THREAD_SIZE / 8)
32 34
33/* 35/*
34 * macros/functions for gaining access to the thread information structure 36 * macros/functions for gaining access to the thread information structure
@@ -50,8 +52,6 @@ struct thread_info {
50#define init_thread_info (init_thread_union.thread_info) 52#define init_thread_info (init_thread_union.thread_info)
51#define init_stack (init_thread_union.stack) 53#define init_stack (init_thread_union.stack)
52 54
53#define THREAD_SIZE (2*PAGE_SIZE)
54
55/* how to get the thread information struct from C */ 55/* how to get the thread information struct from C */
56static inline struct thread_info *current_thread_info(void) 56static inline struct thread_info *current_thread_info(void)
57{ 57{
@@ -73,8 +73,12 @@ static inline struct thread_info *current_thread_info(void)
73} 73}
74 74
75/* thread information allocation */ 75/* thread information allocation */
76#define alloc_thread_info(ti) ((struct thread_info *) __get_free_pages(GFP_KERNEL,1)) 76#ifdef CONFIG_DEBUG_STACK_USAGE
77#define free_thread_info(ti) free_pages((unsigned long) (ti), 1) 77#define alloc_thread_info(ti) kzalloc(THREAD_SIZE, GFP_KERNEL)
78#else
79#define alloc_thread_info(ti) kmalloc(THREAD_SIZE, GFP_KERNEL)
80#endif
81#define free_thread_info(ti) kfree(ti)
78 82
79#else /* !__ASSEMBLY__ */ 83#else /* !__ASSEMBLY__ */
80 84