aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris
diff options
context:
space:
mode:
authorRabin Vincent <rabin@rab.in>2015-05-14 12:19:03 -0400
committerJesper Nilsson <jespern@axis.com>2015-09-04 18:56:50 -0400
commitaa6f4d2b6547a9949d87c9b09a872a7015366588 (patch)
tree6efb66f528d045e050b21889c31937b5b4bbadf6 /arch/cris
parent3fffa23ee0a348aef1b597b67626d4724667143b (diff)
CRIS: add STACKTRACE_SUPPORT
Add stacktrace support, which is required for lockdep and tracing. The stack tracing simply looks at all kernel text symbols found on the stack, similar to the trap stack dumping code, which can also be converted to use this. Signed-off-by: Rabin Vincent <rabin@rab.in> Signed-off-by: Jesper Nilsson <jesper.nilsson@axis.com>
Diffstat (limited to 'arch/cris')
-rw-r--r--arch/cris/Kconfig3
-rw-r--r--arch/cris/include/asm/stacktrace.h8
-rw-r--r--arch/cris/kernel/Makefile1
-rw-r--r--arch/cris/kernel/stacktrace.c76
4 files changed, 88 insertions, 0 deletions
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index e7ba2d4bdd4f..61f4acceb9d4 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -40,6 +40,9 @@ config TRACE_IRQFLAGS_SUPPORT
40 depends on ETRAX_ARCH_V32 40 depends on ETRAX_ARCH_V32
41 def_bool y 41 def_bool y
42 42
43config STACKTRACE_SUPPORT
44 def_bool y
45
43config CRIS 46config CRIS
44 bool 47 bool
45 default y 48 default y
diff --git a/arch/cris/include/asm/stacktrace.h b/arch/cris/include/asm/stacktrace.h
new file mode 100644
index 000000000000..2d90856943ad
--- /dev/null
+++ b/arch/cris/include/asm/stacktrace.h
@@ -0,0 +1,8 @@
1#ifndef __CRIS_STACKTRACE_H
2#define __CRIS_STACKTRACE_H
3
4void walk_stackframe(unsigned long sp,
5 int (*fn)(unsigned long addr, void *data),
6 void *data);
7
8#endif
diff --git a/arch/cris/kernel/Makefile b/arch/cris/kernel/Makefile
index edef71f12bb8..5fae398ca915 100644
--- a/arch/cris/kernel/Makefile
+++ b/arch/cris/kernel/Makefile
@@ -8,6 +8,7 @@ extra-y := vmlinux.lds
8 8
9obj-y := process.o traps.o irq.o ptrace.o setup.o time.o sys_cris.o 9obj-y := process.o traps.o irq.o ptrace.o setup.o time.o sys_cris.o
10obj-y += devicetree.o 10obj-y += devicetree.o
11obj-y += stacktrace.o
11 12
12obj-$(CONFIG_MODULES) += crisksyms.o 13obj-$(CONFIG_MODULES) += crisksyms.o
13obj-$(CONFIG_MODULES) += module.o 14obj-$(CONFIG_MODULES) += module.o
diff --git a/arch/cris/kernel/stacktrace.c b/arch/cris/kernel/stacktrace.c
new file mode 100644
index 000000000000..99838c74456d
--- /dev/null
+++ b/arch/cris/kernel/stacktrace.c
@@ -0,0 +1,76 @@
1#include <linux/sched.h>
2#include <linux/stacktrace.h>
3#include <linux/stacktrace.h>
4#include <asm/stacktrace.h>
5
6void walk_stackframe(unsigned long sp,
7 int (*fn)(unsigned long addr, void *data),
8 void *data)
9{
10 unsigned long high = ALIGN(sp, THREAD_SIZE);
11
12 for (; sp <= high - 4; sp += 4) {
13 unsigned long addr = *(unsigned long *) sp;
14
15 if (!kernel_text_address(addr))
16 continue;
17
18 if (fn(addr, data))
19 break;
20 }
21}
22
23struct stack_trace_data {
24 struct stack_trace *trace;
25 unsigned int no_sched_functions;
26 unsigned int skip;
27};
28
29#ifdef CONFIG_STACKTRACE
30
31static int save_trace(unsigned long addr, void *d)
32{
33 struct stack_trace_data *data = d;
34 struct stack_trace *trace = data->trace;
35
36 if (data->no_sched_functions && in_sched_functions(addr))
37 return 0;
38
39 if (data->skip) {
40 data->skip--;
41 return 0;
42 }
43
44 trace->entries[trace->nr_entries++] = addr;
45
46 return trace->nr_entries >= trace->max_entries;
47}
48
49void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
50{
51 struct stack_trace_data data;
52 unsigned long sp;
53
54 data.trace = trace;
55 data.skip = trace->skip;
56
57 if (tsk != current) {
58 data.no_sched_functions = 1;
59 sp = tsk->thread.ksp;
60 } else {
61 data.no_sched_functions = 0;
62 sp = rdsp();
63 }
64
65 walk_stackframe(sp, save_trace, &data);
66 if (trace->nr_entries < trace->max_entries)
67 trace->entries[trace->nr_entries++] = ULONG_MAX;
68}
69
70void save_stack_trace(struct stack_trace *trace)
71{
72 save_stack_trace_tsk(current, trace);
73}
74EXPORT_SYMBOL_GPL(save_stack_trace);
75
76#endif /* CONFIG_STACKTRACE */