aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMichal Simek <monstr@monstr.eu>2009-11-10 09:57:01 -0500
committerMichal Simek <monstr@monstr.eu>2009-12-14 02:40:09 -0500
commit24b45a12c21132e78e14f3aedf74bb1297228072 (patch)
treedd06c0079e64f00e9e52caed191a84705c9552e3 /arch
parent7cf79d59ea650ae82868a99cc2954871d2a239bf (diff)
microblaze: Stack trace support
This is working implemetation but the problem is that Microblaze misses frame pointer that's why is there big loop which trace and show all addresses which are in text. It shows addresses which are in registers, etc. This is problem and this is the reason why all Microblaze traces are wrong. There is an option to do hacks and trace the kernel code but this is too complicated. Signed-off-by: Michal Simek <monstr@monstr.eu>
Diffstat (limited to 'arch')
-rw-r--r--arch/microblaze/Kconfig3
-rw-r--r--arch/microblaze/kernel/Makefile1
-rw-r--r--arch/microblaze/kernel/stacktrace.c65
3 files changed, 69 insertions, 0 deletions
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index bbd8327f1890..8e1c4f7d3e6e 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -57,6 +57,9 @@ config GENERIC_GPIO
57config GENERIC_CSUM 57config GENERIC_CSUM
58 def_bool y 58 def_bool y
59 59
60config STACKTRACE_SUPPORT
61 def_bool y
62
60config PCI 63config PCI
61 def_bool n 64 def_bool n
62 65
diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile
index fddd0c403d40..c465a5c4669c 100644
--- a/arch/microblaze/kernel/Makefile
+++ b/arch/microblaze/kernel/Makefile
@@ -16,5 +16,6 @@ obj-$(CONFIG_SELFMOD) += selfmod.o
16obj-$(CONFIG_HEART_BEAT) += heartbeat.o 16obj-$(CONFIG_HEART_BEAT) += heartbeat.o
17obj-$(CONFIG_MODULES) += microblaze_ksyms.o module.o 17obj-$(CONFIG_MODULES) += microblaze_ksyms.o module.o
18obj-$(CONFIG_MMU) += misc.o 18obj-$(CONFIG_MMU) += misc.o
19obj-$(CONFIG_STACKTRACE) += stacktrace.o
19 20
20obj-y += entry$(MMU).o 21obj-y += entry$(MMU).o
diff --git a/arch/microblaze/kernel/stacktrace.c b/arch/microblaze/kernel/stacktrace.c
new file mode 100644
index 000000000000..123692f22647
--- /dev/null
+++ b/arch/microblaze/kernel/stacktrace.c
@@ -0,0 +1,65 @@
1/*
2 * Stack trace support for Microblaze.
3 *
4 * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
5 * Copyright (C) 2009 PetaLogix
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11
12#include <linux/sched.h>
13#include <linux/stacktrace.h>
14#include <linux/thread_info.h>
15#include <linux/ptrace.h>
16#include <linux/module.h>
17
18/* FIXME initial support */
19void save_stack_trace(struct stack_trace *trace)
20{
21 unsigned long *sp;
22 unsigned long addr;
23 asm("addik %0, r1, 0" : "=r" (sp));
24
25 while (!kstack_end(sp)) {
26 addr = *sp++;
27 if (__kernel_text_address(addr)) {
28 if (trace->skip > 0)
29 trace->skip--;
30 else
31 trace->entries[trace->nr_entries++] = addr;
32
33 if (trace->nr_entries >= trace->max_entries)
34 break;
35 }
36 }
37}
38EXPORT_SYMBOL_GPL(save_stack_trace);
39
40void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
41{
42 unsigned int *sp;
43 unsigned long addr;
44
45 struct thread_info *ti = task_thread_info(tsk);
46
47 if (tsk == current)
48 asm("addik %0, r1, 0" : "=r" (sp));
49 else
50 sp = (unsigned int *)ti->cpu_context.r1;
51
52 while (!kstack_end(sp)) {
53 addr = *sp++;
54 if (__kernel_text_address(addr)) {
55 if (trace->skip > 0)
56 trace->skip--;
57 else
58 trace->entries[trace->nr_entries++] = addr;
59
60 if (trace->nr_entries >= trace->max_entries)
61 break;
62 }
63 }
64}
65EXPORT_SYMBOL_GPL(save_stack_trace_tsk);