aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2006-12-04 04:17:28 -0500
committerPaul Mundt <lethal@linux-sh.org>2006-12-05 20:45:40 -0500
commitafbfb52e47273a440df33274452c603e8c332de2 (patch)
tree041dc70061a67e787b362959298e093830b4b4d7 /arch/sh/kernel
parentc03c69610bfa728805deceeb624ee4268c722a5a (diff)
sh: stacktrace/lockdep/irqflags tracing support.
Wire up all of the essentials for lockdep.. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r--arch/sh/kernel/Makefile1
-rw-r--r--arch/sh/kernel/cpu/sh2/entry.S16
-rw-r--r--arch/sh/kernel/cpu/sh3/entry.S2
-rw-r--r--arch/sh/kernel/entry-common.S64
-rw-r--r--arch/sh/kernel/stacktrace.c43
5 files changed, 124 insertions, 2 deletions
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 50d54c24d76..99c7e5249f7 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -21,3 +21,4 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
21obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 21obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
22obj-$(CONFIG_APM) += apm.o 22obj-$(CONFIG_APM) += apm.o
23obj-$(CONFIG_PM) += pm.o 23obj-$(CONFIG_PM) += pm.o
24obj-$(CONFIG_STACKTRACE) += stacktrace.o
diff --git a/arch/sh/kernel/cpu/sh2/entry.S b/arch/sh/kernel/cpu/sh2/entry.S
index 298d9191909..34d51b3745e 100644
--- a/arch/sh/kernel/cpu/sh2/entry.S
+++ b/arch/sh/kernel/cpu/sh2/entry.S
@@ -184,6 +184,11 @@ trap_entry:
184 add r15,r8 184 add r15,r8
185 mov.l r9,@r8 185 mov.l r9,@r8
186 mov r9,r8 186 mov r9,r8
187#ifdef CONFIG_TRACE_IRQFLAGS
188 mov.l 5f, r9
189 jsr @r9
190 nop
191#endif
187 sti 192 sti
188 bra system_call 193 bra system_call
189 nop 194 nop
@@ -193,6 +198,9 @@ trap_entry:
1932: .long break_point_trap_software 1982: .long break_point_trap_software
1943: .long NR_syscalls 1993: .long NR_syscalls
1954: .long sys_call_table 2004: .long sys_call_table
201#ifdef CONFIG_TRACE_IRQFLAGS
2025: .long trace_hardirqs_on
203#endif
196 204
197#if defined(CONFIG_SH_STANDARD_BIOS) 205#if defined(CONFIG_SH_STANDARD_BIOS)
198 /* Unwind the stack and jmp to the debug entry */ 206 /* Unwind the stack and jmp to the debug entry */
@@ -255,6 +263,11 @@ ENTRY(address_error_handler)
255 263
256restore_all: 264restore_all:
257 cli 265 cli
266#ifdef CONFIG_TRACE_IRQFLAGS
267 mov.l 3f, r0
268 jsr @r0
269 nop
270#endif
258 mov r15,r0 271 mov r15,r0
259 mov.l $cpu_mode,r2 272 mov.l $cpu_mode,r2
260 mov #OFF_SR,r3 273 mov #OFF_SR,r3
@@ -307,6 +320,9 @@ $current_thread_info:
307 .long __current_thread_info 320 .long __current_thread_info
308$cpu_mode: 321$cpu_mode:
309 .long __cpu_mode 322 .long __cpu_mode
323#ifdef CONFIG_TRACE_IRQFLAGS
3243: .long trace_hardirqs_off
325#endif
310 326
311! common exception handler 327! common exception handler
312#include "../../entry-common.S" 328#include "../../entry-common.S"
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index 7ba3dcbe750..8c0dc2700c6 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -140,7 +140,7 @@ call_dpf:
140 mov.l 1f, r0 140 mov.l 1f, r0
141 mov.l @r0, r6 ! address 141 mov.l @r0, r6 ! address
142 mov.l 3f, r0 142 mov.l 3f, r0
143 sti 143
144 jmp @r0 144 jmp @r0
145 mov r15, r4 ! regs 145 mov r15, r4 ! regs
146 146
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index 8f96d21fcb1..29136a35d7c 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -100,6 +100,11 @@ debug_trap:
100 .align 2 100 .align 2
101ENTRY(exception_error) 101ENTRY(exception_error)
102 ! 102 !
103#ifdef CONFIG_TRACE_IRQFLAGS
104 mov.l 3f, r0
105 jsr @r0
106 nop
107#endif
103 sti 108 sti
104 mov.l 2f, r0 109 mov.l 2f, r0
105 jmp @r0 110 jmp @r0
@@ -109,10 +114,18 @@ ENTRY(exception_error)
109 .align 2 114 .align 2
1101: .long break_point_trap_software 1151: .long break_point_trap_software
1112: .long do_exception_error 1162: .long do_exception_error
117#ifdef CONFIG_TRACE_IRQFLAGS
1183: .long trace_hardirqs_on
119#endif
112 120
113 .align 2 121 .align 2
114ret_from_exception: 122ret_from_exception:
115 preempt_stop() 123 preempt_stop()
124#ifdef CONFIG_TRACE_IRQFLAGS
125 mov.l 4f, r0
126 jsr @r0
127 nop
128#endif
116ENTRY(ret_from_irq) 129ENTRY(ret_from_irq)
117 ! 130 !
118 mov #OFF_SR, r0 131 mov #OFF_SR, r0
@@ -143,6 +156,11 @@ need_resched:
143 mov.l 1f, r0 156 mov.l 1f, r0
144 mov.l r0, @(TI_PRE_COUNT,r8) 157 mov.l r0, @(TI_PRE_COUNT,r8)
145 158
159#ifdef CONFIG_TRACE_IRQFLAGS
160 mov.l 3f, r0
161 jsr @r0
162 nop
163#endif
146 sti 164 sti
147 mov.l 2f, r0 165 mov.l 2f, r0
148 jsr @r0 166 jsr @r0
@@ -150,9 +168,15 @@ need_resched:
150 mov #0, r0 168 mov #0, r0
151 mov.l r0, @(TI_PRE_COUNT,r8) 169 mov.l r0, @(TI_PRE_COUNT,r8)
152 cli 170 cli
171#ifdef CONFIG_TRACE_IRQFLAGS
172 mov.l 4f, r0
173 jsr @r0
174 nop
175#endif
153 176
154 bra need_resched 177 bra need_resched
155 nop 178 nop
179
156noresched: 180noresched:
157 bra __restore_all 181 bra __restore_all
158 nop 182 nop
@@ -160,11 +184,20 @@ noresched:
160 .align 2 184 .align 2
1611: .long PREEMPT_ACTIVE 1851: .long PREEMPT_ACTIVE
1622: .long schedule 1862: .long schedule
187#ifdef CONFIG_TRACE_IRQFLAGS
1883: .long trace_hardirqs_on
1894: .long trace_hardirqs_off
190#endif
163#endif 191#endif
164 192
165ENTRY(resume_userspace) 193ENTRY(resume_userspace)
166 ! r8: current_thread_info 194 ! r8: current_thread_info
167 cli 195 cli
196#ifdef CONFIG_TRACE_IRQFLAGS
197 mov.l 5f, r0
198 jsr @r0
199 nop
200#endif
168 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags 201 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
169 tst #_TIF_WORK_MASK, r0 202 tst #_TIF_WORK_MASK, r0
170 bt/s __restore_all 203 bt/s __restore_all
@@ -210,6 +243,11 @@ work_resched:
210 jsr @r1 ! schedule 243 jsr @r1 ! schedule
211 nop 244 nop
212 cli 245 cli
246#ifdef CONFIG_TRACE_IRQFLAGS
247 mov.l 5f, r0
248 jsr @r0
249 nop
250#endif
213 ! 251 !
214 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags 252 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
215 tst #_TIF_WORK_MASK, r0 253 tst #_TIF_WORK_MASK, r0
@@ -221,6 +259,10 @@ work_resched:
2211: .long schedule 2591: .long schedule
2222: .long do_notify_resume 2602: .long do_notify_resume
2233: .long restore_all 2613: .long restore_all
262#ifdef CONFIG_TRACE_IRQFLAGS
2634: .long trace_hardirqs_on
2645: .long trace_hardirqs_off
265#endif
224 266
225 .align 2 267 .align 2
226syscall_exit_work: 268syscall_exit_work:
@@ -229,6 +271,11 @@ syscall_exit_work:
229 tst #_TIF_SYSCALL_TRACE, r0 271 tst #_TIF_SYSCALL_TRACE, r0
230 bt/s work_pending 272 bt/s work_pending
231 tst #_TIF_NEED_RESCHED, r0 273 tst #_TIF_NEED_RESCHED, r0
274#ifdef CONFIG_TRACE_IRQFLAGS
275 mov.l 5f, r0
276 jsr @r0
277 nop
278#endif
232 sti 279 sti
233 ! XXX setup arguments... 280 ! XXX setup arguments...
234 mov.l 4f, r0 ! do_syscall_trace 281 mov.l 4f, r0 ! do_syscall_trace
@@ -265,7 +312,7 @@ syscall_trace_entry:
265 mov.l r0, @(OFF_R0,r15) ! Return value 312 mov.l r0, @(OFF_R0,r15) ! Return value
266 313
267__restore_all: 314__restore_all:
268 mov.l 1f,r0 315 mov.l 1f, r0
269 jmp @r0 316 jmp @r0
270 nop 317 nop
271 318
@@ -331,7 +378,13 @@ ENTRY(system_call)
331 mov #OFF_TRA, r9 378 mov #OFF_TRA, r9
332 add r15, r9 379 add r15, r9
333 mov.l r8, @r9 ! set TRA value to tra 380 mov.l r8, @r9 ! set TRA value to tra
381#ifdef CONFIG_TRACE_IRQFLAGS
382 mov.l 5f, r10
383 jsr @r10
384 nop
385#endif
334 sti 386 sti
387
335 ! 388 !
336 get_current_thread_info r8, r10 389 get_current_thread_info r8, r10
337 mov.l @(TI_FLAGS,r8), r8 390 mov.l @(TI_FLAGS,r8), r8
@@ -355,6 +408,11 @@ syscall_call:
355 ! 408 !
356syscall_exit: 409syscall_exit:
357 cli 410 cli
411#ifdef CONFIG_TRACE_IRQFLAGS
412 mov.l 6f, r0
413 jsr @r0
414 nop
415#endif
358 ! 416 !
359 get_current_thread_info r8, r0 417 get_current_thread_info r8, r0
360 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags 418 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
@@ -369,3 +427,7 @@ syscall_exit:
3692: .long NR_syscalls 4272: .long NR_syscalls
3703: .long sys_call_table 4283: .long sys_call_table
3714: .long do_syscall_trace 4294: .long do_syscall_trace
430#ifdef CONFIG_TRACE_IRQFLAGS
4315: .long trace_hardirqs_on
4326: .long trace_hardirqs_off
433#endif
diff --git a/arch/sh/kernel/stacktrace.c b/arch/sh/kernel/stacktrace.c
new file mode 100644
index 00000000000..0d5268afe80
--- /dev/null
+++ b/arch/sh/kernel/stacktrace.c
@@ -0,0 +1,43 @@
1/*
2 * arch/sh/kernel/stacktrace.c
3 *
4 * Stack trace management functions
5 *
6 * Copyright (C) 2006 Paul Mundt
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 */
12#include <linux/sched.h>
13#include <linux/stacktrace.h>
14#include <linux/thread_info.h>
15#include <asm/ptrace.h>
16
17/*
18 * Save stack-backtrace addresses into a stack_trace buffer.
19 */
20void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
21{
22 unsigned long *sp;
23
24 if (!task)
25 task = current;
26 if (task == current)
27 sp = (unsigned long *)current_stack_pointer;
28 else
29 sp = (unsigned long *)task->thread.sp;
30
31 while (!kstack_end(sp)) {
32 unsigned long addr = *sp++;
33
34 if (__kernel_text_address(addr)) {
35 if (trace->skip > 0)
36 trace->skip--;
37 else
38 trace->entries[trace->nr_entries++] = addr;
39 if (trace->nr_entries >= trace->max_entries)
40 break;
41 }
42 }
43}