aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/stacktrace.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-18 12:43:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-18 12:43:09 -0400
commit515b696b282f856c3ad1679ccd658120faa387d0 (patch)
treed9d7c1185c396617f128ca23463062308d11393b /arch/sh/kernel/stacktrace.c
parentfa877c71e2136bd682b45022c96d5e073ced9f58 (diff)
parent064a16dc41be879d12bd5de5d2f9d38d890e0ee7 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: (262 commits) sh: mach-ecovec24: Add user debug switch support sh: Kill off unused se_skipped in alignment trap notification code. sh: Wire up HAVE_SYSCALL_TRACEPOINTS. video: sh_mobile_lcdcfb: use both register sets for display panning video: sh_mobile_lcdcfb: implement display panning sh: Fix up sh7705 flush_dcache_page() build. sh: kfr2r09: document the PLL/FLL <-> RF relationship. sh: mach-ecovec24: need asm/clock.h. sh: mach-ecovec24: deassert usb irq on boot. sh: Add KEYSC support for EcoVec24 sh: add kycr2_delay for sh_keysc sh: cpufreq: Include CPU id in info messages. sh: multi-evt support for SH-X3 proto CPU. sh: clkfwk: remove bogus set_bus_parent() from SH7709. sh: Fix the indication point of the liquid crystal of AP-325RXA(AP3300) sh: Add EcoVec24 romImage defconfig sh: USB disable process is needed if romImage boot for EcoVec24 sh: EcoVec24: add HIZA setting for LED sh: EcoVec24: write MAC address in boot sh: Add romImage support for EcoVec24 ...
Diffstat (limited to 'arch/sh/kernel/stacktrace.c')
-rw-r--r--arch/sh/kernel/stacktrace.c98
1 files changed, 72 insertions, 26 deletions
diff --git a/arch/sh/kernel/stacktrace.c b/arch/sh/kernel/stacktrace.c
index 1a2a5eb76e41..c2e45c48409c 100644
--- a/arch/sh/kernel/stacktrace.c
+++ b/arch/sh/kernel/stacktrace.c
@@ -13,47 +13,93 @@
13#include <linux/stacktrace.h> 13#include <linux/stacktrace.h>
14#include <linux/thread_info.h> 14#include <linux/thread_info.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <asm/unwinder.h>
16#include <asm/ptrace.h> 17#include <asm/ptrace.h>
18#include <asm/stacktrace.h>
19
20static void save_stack_warning(void *data, char *msg)
21{
22}
23
24static void
25save_stack_warning_symbol(void *data, char *msg, unsigned long symbol)
26{
27}
28
29static int save_stack_stack(void *data, char *name)
30{
31 return 0;
32}
17 33
18/* 34/*
19 * Save stack-backtrace addresses into a stack_trace buffer. 35 * Save stack-backtrace addresses into a stack_trace buffer.
20 */ 36 */
37static void save_stack_address(void *data, unsigned long addr, int reliable)
38{
39 struct stack_trace *trace = data;
40
41 if (!reliable)
42 return;
43
44 if (trace->skip > 0) {
45 trace->skip--;
46 return;
47 }
48
49 if (trace->nr_entries < trace->max_entries)
50 trace->entries[trace->nr_entries++] = addr;
51}
52
53static const struct stacktrace_ops save_stack_ops = {
54 .warning = save_stack_warning,
55 .warning_symbol = save_stack_warning_symbol,
56 .stack = save_stack_stack,
57 .address = save_stack_address,
58};
59
21void save_stack_trace(struct stack_trace *trace) 60void save_stack_trace(struct stack_trace *trace)
22{ 61{
23 unsigned long *sp = (unsigned long *)current_stack_pointer; 62 unsigned long *sp = (unsigned long *)current_stack_pointer;
24 63
25 while (!kstack_end(sp)) { 64 unwind_stack(current, NULL, sp, &save_stack_ops, trace);
26 unsigned long addr = *sp++; 65 if (trace->nr_entries < trace->max_entries)
27 66 trace->entries[trace->nr_entries++] = ULONG_MAX;
28 if (__kernel_text_address(addr)) {
29 if (trace->skip > 0)
30 trace->skip--;
31 else
32 trace->entries[trace->nr_entries++] = addr;
33 if (trace->nr_entries >= trace->max_entries)
34 break;
35 }
36 }
37} 67}
38EXPORT_SYMBOL_GPL(save_stack_trace); 68EXPORT_SYMBOL_GPL(save_stack_trace);
39 69
70static void
71save_stack_address_nosched(void *data, unsigned long addr, int reliable)
72{
73 struct stack_trace *trace = (struct stack_trace *)data;
74
75 if (!reliable)
76 return;
77
78 if (in_sched_functions(addr))
79 return;
80
81 if (trace->skip > 0) {
82 trace->skip--;
83 return;
84 }
85
86 if (trace->nr_entries < trace->max_entries)
87 trace->entries[trace->nr_entries++] = addr;
88}
89
90static const struct stacktrace_ops save_stack_ops_nosched = {
91 .warning = save_stack_warning,
92 .warning_symbol = save_stack_warning_symbol,
93 .stack = save_stack_stack,
94 .address = save_stack_address_nosched,
95};
96
40void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) 97void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
41{ 98{
42 unsigned long *sp = (unsigned long *)tsk->thread.sp; 99 unsigned long *sp = (unsigned long *)tsk->thread.sp;
43 100
44 while (!kstack_end(sp)) { 101 unwind_stack(current, NULL, sp, &save_stack_ops_nosched, trace);
45 unsigned long addr = *sp++; 102 if (trace->nr_entries < trace->max_entries)
46 103 trace->entries[trace->nr_entries++] = ULONG_MAX;
47 if (__kernel_text_address(addr)) {
48 if (in_sched_functions(addr))
49 break;
50 if (trace->skip > 0)
51 trace->skip--;
52 else
53 trace->entries[trace->nr_entries++] = addr;
54 if (trace->nr_entries >= trace->max_entries)
55 break;
56 }
57 }
58} 104}
59EXPORT_SYMBOL_GPL(save_stack_trace_tsk); 105EXPORT_SYMBOL_GPL(save_stack_trace_tsk);