diff options
Diffstat (limited to 'arch/sh/lib/mcount.S')
-rw-r--r-- | arch/sh/lib/mcount.S | 85 |
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; \ | ||
77 | 1: | ||
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 | ||
160 | stack_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 */ | ||