aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/lib
diff options
context:
space:
mode:
authorMatt Fleming <matt@console-pimps.org>2009-07-10 21:00:23 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-07-10 21:07:58 -0400
commitb99610fb9cdf390965c62c22322596d961591160 (patch)
tree0c836b4390370b4848f151e3b3cbe27e6d8b48e2 /arch/sh/lib
parentc652d780c9cf7f860141de232b37160fe013feca (diff)
sh: Provide diagnostic kernel stack checks
Enable kernel stack checking code in both the dynamic ftrace and mcount code paths. Check the stack to see if it's overflowing and make sure that the stack pointer contains an address that's either in init_stack or after the bss. Signed-off-by: Matt Fleming <matt@console-pimps.org> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/lib')
-rw-r--r--arch/sh/lib/mcount.S85
1 files changed, 85 insertions, 0 deletions
diff --git a/arch/sh/lib/mcount.S b/arch/sh/lib/mcount.S
index 71e87f9b4fda..8596483f7b41 100644
--- a/arch/sh/lib/mcount.S
+++ b/arch/sh/lib/mcount.S
@@ -9,6 +9,8 @@
9 * for more details. 9 * for more details.
10 */ 10 */
11#include <asm/ftrace.h> 11#include <asm/ftrace.h>
12#include <asm/thread_info.h>
13#include <asm/asm-offsets.h>
12 14
13#define MCOUNT_ENTER() \ 15#define MCOUNT_ENTER() \
14 mov.l r4, @-r15; \ 16 mov.l r4, @-r15; \
@@ -28,6 +30,55 @@
28 rts; \ 30 rts; \
29 mov.l @r15+, r4 31 mov.l @r15+, r4
30 32
33#ifdef CONFIG_STACK_DEBUG
34/*
35 * Perform diagnostic checks on the state of the kernel stack.
36 *
37 * Check for stack overflow. If there is less than 1KB free
38 * then it has overflowed.
39 *
40 * Make sure the stack pointer contains a valid address. Valid
41 * addresses for kernel stacks are anywhere after the bss
42 * (after _ebss) and anywhere in init_thread_union (init_stack).
43 */
44#define STACK_CHECK() \
45 mov #(THREAD_SIZE >> 10), r0; \
46 shll8 r0; \
47 shll2 r0; \
48 \
49 /* r1 = sp & (THREAD_SIZE - 1) */ \
50 mov #-1, r1; \
51 add r0, r1; \
52 and r15, r1; \
53 \
54 mov #TI_SIZE, r3; \
55 mov #(STACK_WARN >> 8), r2; \
56 shll8 r2; \
57 add r3, r2; \
58 \
59 /* Is the stack overflowing? */ \
60 cmp/hi r2, r1; \
61 bf stack_panic; \
62 \
63 /* If sp > _ebss then we're OK. */ \
64 mov.l .L_ebss, r1; \
65 cmp/hi r1, r15; \
66 bt 1f; \
67 \
68 /* If sp < init_stack, we're not OK. */ \
69 mov.l .L_init_thread_union, r1; \
70 cmp/hs r1, r15; \
71 bf stack_panic; \
72 \
73 /* If sp > init_stack && sp < _ebss, not OK. */ \
74 add r0, r1; \
75 cmp/hs r1, r15; \
76 bt stack_panic; \
771:
78#else
79#define STACK_CHECK()
80#endif /* CONFIG_STACK_DEBUG */
81
31 .align 2 82 .align 2
32 .globl _mcount 83 .globl _mcount
33 .type _mcount,@function 84 .type _mcount,@function
@@ -41,6 +92,8 @@ mcount:
41 tst r0, r0 92 tst r0, r0
42 bf ftrace_stub 93 bf ftrace_stub
43#endif 94#endif
95 STACK_CHECK()
96
44 MCOUNT_ENTER() 97 MCOUNT_ENTER()
45 98
46#ifdef CONFIG_DYNAMIC_FTRACE 99#ifdef CONFIG_DYNAMIC_FTRACE
@@ -73,6 +126,8 @@ ftrace_caller:
73 tst r0, r0 126 tst r0, r0
74 bf ftrace_stub 127 bf ftrace_stub
75 128
129 STACK_CHECK()
130
76 MCOUNT_ENTER() 131 MCOUNT_ENTER()
77 132
78 .globl ftrace_call 133 .globl ftrace_call
@@ -100,6 +155,36 @@ ftrace_stub:
100 rts 155 rts
101 nop 156 nop
102 157
158#ifdef CONFIG_STACK_DEBUG
159 .globl stack_panic
160stack_panic:
161 mov.l .Ldump_stack, r0
162 jsr @r0
163 nop
164
165 mov.l .Lpanic, r0
166 jsr @r0
167 mov.l .Lpanic_s, r4
168
169 rts
170 nop
171
103 .align 2 172 .align 2
104.Lfunction_trace_stop: 173.Lfunction_trace_stop:
105 .long function_trace_stop 174 .long function_trace_stop
175.L_ebss:
176 .long _ebss
177.L_init_thread_union:
178 .long init_thread_union
179.Lpanic:
180 .long panic
181.Lpanic_s:
182 .long .Lpanic_str
183.Ldump_stack:
184 .long dump_stack
185
186 .section .rodata
187 .align 2
188.Lpanic_str:
189 .string "Stack error"
190#endif /* CONFIG_STACK_DEBUG */