Skip to content

Commit

Permalink
sh: stacktrace/lockdep/irqflags tracing support.
Browse files Browse the repository at this point in the history
Wire up all of the essentials for lockdep..

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
  • Loading branch information
pmundt committed Dec 6, 2006
1 parent c03c696 commit afbfb52
Show file tree
Hide file tree
Showing 11 changed files with 289 additions and 103 deletions.
8 changes: 8 additions & 0 deletions arch/sh/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ config GENERIC_TIME
config ARCH_MAY_HAVE_PC_FDC
bool

config STACKTRACE_SUPPORT
bool
default y

config LOCKDEP_SUPPORT
bool
default y

source "init/Kconfig"

menu "System type"
Expand Down
4 changes: 4 additions & 0 deletions arch/sh/Kconfig.debug
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
menu "Kernel hacking"

config TRACE_IRQFLAGS_SUPPORT
bool
default y

source "lib/Kconfig.debug"

config SH_STANDARD_BIOS
Expand Down
1 change: 1 addition & 0 deletions arch/sh/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_APM) += apm.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
16 changes: 16 additions & 0 deletions arch/sh/kernel/cpu/sh2/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,11 @@ trap_entry:
add r15,r8
mov.l r9,@r8
mov r9,r8
#ifdef CONFIG_TRACE_IRQFLAGS
mov.l 5f, r9
jsr @r9
nop
#endif
sti
bra system_call
nop
Expand All @@ -193,6 +198,9 @@ trap_entry:
2: .long break_point_trap_software
3: .long NR_syscalls
4: .long sys_call_table
#ifdef CONFIG_TRACE_IRQFLAGS
5: .long trace_hardirqs_on
#endif

#if defined(CONFIG_SH_STANDARD_BIOS)
/* Unwind the stack and jmp to the debug entry */
Expand Down Expand Up @@ -255,6 +263,11 @@ ENTRY(address_error_handler)

restore_all:
cli
#ifdef CONFIG_TRACE_IRQFLAGS
mov.l 3f, r0
jsr @r0
nop
#endif
mov r15,r0
mov.l $cpu_mode,r2
mov #OFF_SR,r3
Expand Down Expand Up @@ -307,6 +320,9 @@ $current_thread_info:
.long __current_thread_info
$cpu_mode:
.long __cpu_mode
#ifdef CONFIG_TRACE_IRQFLAGS
3: .long trace_hardirqs_off
#endif

! common exception handler
#include "../../entry-common.S"
Expand Down
2 changes: 1 addition & 1 deletion arch/sh/kernel/cpu/sh3/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ call_dpf:
mov.l 1f, r0
mov.l @r0, r6 ! address
mov.l 3f, r0
sti

jmp @r0
mov r15, r4 ! regs

Expand Down
64 changes: 63 additions & 1 deletion arch/sh/kernel/entry-common.S
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ debug_trap:
.align 2
ENTRY(exception_error)
!
#ifdef CONFIG_TRACE_IRQFLAGS
mov.l 3f, r0
jsr @r0
nop
#endif
sti
mov.l 2f, r0
jmp @r0
Expand All @@ -109,10 +114,18 @@ ENTRY(exception_error)
.align 2
1: .long break_point_trap_software
2: .long do_exception_error
#ifdef CONFIG_TRACE_IRQFLAGS
3: .long trace_hardirqs_on
#endif

.align 2
ret_from_exception:
preempt_stop()
#ifdef CONFIG_TRACE_IRQFLAGS
mov.l 4f, r0
jsr @r0
nop
#endif
ENTRY(ret_from_irq)
!
mov #OFF_SR, r0
Expand Down Expand Up @@ -143,28 +156,48 @@ need_resched:
mov.l 1f, r0
mov.l r0, @(TI_PRE_COUNT,r8)

#ifdef CONFIG_TRACE_IRQFLAGS
mov.l 3f, r0
jsr @r0
nop
#endif
sti
mov.l 2f, r0
jsr @r0
nop
mov #0, r0
mov.l r0, @(TI_PRE_COUNT,r8)
cli
#ifdef CONFIG_TRACE_IRQFLAGS
mov.l 4f, r0
jsr @r0
nop
#endif

bra need_resched
nop

noresched:
bra __restore_all
nop

.align 2
1: .long PREEMPT_ACTIVE
2: .long schedule
#ifdef CONFIG_TRACE_IRQFLAGS
3: .long trace_hardirqs_on
4: .long trace_hardirqs_off
#endif
#endif

ENTRY(resume_userspace)
! r8: current_thread_info
cli
#ifdef CONFIG_TRACE_IRQFLAGS
mov.l 5f, r0
jsr @r0
nop
#endif
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
tst #_TIF_WORK_MASK, r0
bt/s __restore_all
Expand Down Expand Up @@ -210,6 +243,11 @@ work_resched:
jsr @r1 ! schedule
nop
cli
#ifdef CONFIG_TRACE_IRQFLAGS
mov.l 5f, r0
jsr @r0
nop
#endif
!
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
tst #_TIF_WORK_MASK, r0
Expand All @@ -221,6 +259,10 @@ work_resched:
1: .long schedule
2: .long do_notify_resume
3: .long restore_all
#ifdef CONFIG_TRACE_IRQFLAGS
4: .long trace_hardirqs_on
5: .long trace_hardirqs_off
#endif

.align 2
syscall_exit_work:
Expand All @@ -229,6 +271,11 @@ syscall_exit_work:
tst #_TIF_SYSCALL_TRACE, r0
bt/s work_pending
tst #_TIF_NEED_RESCHED, r0
#ifdef CONFIG_TRACE_IRQFLAGS
mov.l 5f, r0
jsr @r0
nop
#endif
sti
! XXX setup arguments...
mov.l 4f, r0 ! do_syscall_trace
Expand Down Expand Up @@ -265,7 +312,7 @@ syscall_trace_entry:
mov.l r0, @(OFF_R0,r15) ! Return value

__restore_all:
mov.l 1f,r0
mov.l 1f, r0
jmp @r0
nop

Expand Down Expand Up @@ -331,7 +378,13 @@ ENTRY(system_call)
mov #OFF_TRA, r9
add r15, r9
mov.l r8, @r9 ! set TRA value to tra
#ifdef CONFIG_TRACE_IRQFLAGS
mov.l 5f, r10
jsr @r10
nop
#endif
sti

!
get_current_thread_info r8, r10
mov.l @(TI_FLAGS,r8), r8
Expand All @@ -355,6 +408,11 @@ syscall_call:
!
syscall_exit:
cli
#ifdef CONFIG_TRACE_IRQFLAGS
mov.l 6f, r0
jsr @r0
nop
#endif
!
get_current_thread_info r8, r0
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
Expand All @@ -369,3 +427,7 @@ syscall_exit:
2: .long NR_syscalls
3: .long sys_call_table
4: .long do_syscall_trace
#ifdef CONFIG_TRACE_IRQFLAGS
5: .long trace_hardirqs_on
6: .long trace_hardirqs_off
#endif
43 changes: 43 additions & 0 deletions arch/sh/kernel/stacktrace.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* arch/sh/kernel/stacktrace.c
*
* Stack trace management functions
*
* Copyright (C) 2006 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
#include <linux/sched.h>
#include <linux/stacktrace.h>
#include <linux/thread_info.h>
#include <asm/ptrace.h>

/*
* Save stack-backtrace addresses into a stack_trace buffer.
*/
void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
{
unsigned long *sp;

if (!task)
task = current;
if (task == current)
sp = (unsigned long *)current_stack_pointer;
else
sp = (unsigned long *)task->thread.sp;

while (!kstack_end(sp)) {
unsigned long addr = *sp++;

if (__kernel_text_address(addr)) {
if (trace->skip > 0)
trace->skip--;
else
trace->entries[trace->nr_entries++] = addr;
if (trace->nr_entries >= trace->max_entries)
break;
}
}
}
3 changes: 3 additions & 0 deletions arch/sh/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
int si_code;
siginfo_t info;

trace_hardirqs_on();
local_irq_enable();

#ifdef CONFIG_SH_KGDB
if (kgdb_nofault && kgdb_bus_err_hook)
kgdb_bus_err_hook();
Expand Down
Loading

0 comments on commit afbfb52

Please sign in to comment.