diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/parisc/Kconfig | 6 | ||||
-rw-r--r-- | arch/parisc/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/parisc/kernel/stacktrace.c | 63 |
3 files changed, 70 insertions, 0 deletions
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index aacf11d33723..4866e2f8d3bb 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig | |||
@@ -75,6 +75,9 @@ config GENERIC_HARDIRQS | |||
75 | config GENERIC_IRQ_PROBE | 75 | config GENERIC_IRQ_PROBE |
76 | def_bool y | 76 | def_bool y |
77 | 77 | ||
78 | config HAVE_LATENCYTOP_SUPPORT | ||
79 | def_bool y | ||
80 | |||
78 | config IRQ_PER_CPU | 81 | config IRQ_PER_CPU |
79 | bool | 82 | bool |
80 | default y | 83 | default y |
@@ -83,6 +86,9 @@ config IRQ_PER_CPU | |||
83 | config PM | 86 | config PM |
84 | bool | 87 | bool |
85 | 88 | ||
89 | config STACKTRACE_SUPPORT | ||
90 | def_bool y | ||
91 | |||
86 | config ISA_DMA_API | 92 | config ISA_DMA_API |
87 | bool | 93 | bool |
88 | 94 | ||
diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile index 016d3fc4111c..a7ba8cd9417f 100644 --- a/arch/parisc/kernel/Makefile +++ b/arch/parisc/kernel/Makefile | |||
@@ -16,5 +16,6 @@ obj-$(CONFIG_PA11) += pci-dma.o | |||
16 | obj-$(CONFIG_PCI) += pci.o | 16 | obj-$(CONFIG_PCI) += pci.o |
17 | obj-$(CONFIG_MODULES) += module.o | 17 | obj-$(CONFIG_MODULES) += module.o |
18 | obj-$(CONFIG_64BIT) += binfmt_elf32.o sys_parisc32.o signal32.o | 18 | obj-$(CONFIG_64BIT) += binfmt_elf32.o sys_parisc32.o signal32.o |
19 | obj-$(CONFIG_STACKTRACE)+= stacktrace.o | ||
19 | # only supported for PCX-W/U in 64-bit mode at the moment | 20 | # only supported for PCX-W/U in 64-bit mode at the moment |
20 | obj-$(CONFIG_64BIT) += perf.o perf_asm.o | 21 | obj-$(CONFIG_64BIT) += perf.o perf_asm.o |
diff --git a/arch/parisc/kernel/stacktrace.c b/arch/parisc/kernel/stacktrace.c new file mode 100644 index 000000000000..2fe914c5f533 --- /dev/null +++ b/arch/parisc/kernel/stacktrace.c | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * Stack trace management functions | ||
3 | * | ||
4 | * Copyright (C) 2009 Helge Deller <deller@gmx.de> | ||
5 | * based on arch/x86/kernel/stacktrace.c by Ingo Molnar <mingo@redhat.com> | ||
6 | * and parisc unwind functions by Randolph Chung <tausq@debian.org> | ||
7 | * | ||
8 | * TODO: Userspace stacktrace (CONFIG_USER_STACKTRACE_SUPPORT) | ||
9 | */ | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/stacktrace.h> | ||
12 | |||
13 | #include <asm/unwind.h> | ||
14 | |||
15 | static void dump_trace(struct task_struct *task, struct stack_trace *trace) | ||
16 | { | ||
17 | struct unwind_frame_info info; | ||
18 | |||
19 | /* initialize unwind info */ | ||
20 | if (task == current) { | ||
21 | unsigned long sp; | ||
22 | struct pt_regs r; | ||
23 | HERE: | ||
24 | asm volatile ("copy %%r30, %0" : "=r"(sp)); | ||
25 | memset(&r, 0, sizeof(struct pt_regs)); | ||
26 | r.iaoq[0] = (unsigned long)&&HERE; | ||
27 | r.gr[2] = (unsigned long)__builtin_return_address(0); | ||
28 | r.gr[30] = sp; | ||
29 | unwind_frame_init(&info, task, &r); | ||
30 | } else { | ||
31 | unwind_frame_init_from_blocked_task(&info, task); | ||
32 | } | ||
33 | |||
34 | /* unwind stack and save entries in stack_trace struct */ | ||
35 | trace->nr_entries = 0; | ||
36 | while (trace->nr_entries < trace->max_entries) { | ||
37 | if (unwind_once(&info) < 0 || info.ip == 0) | ||
38 | break; | ||
39 | |||
40 | if (__kernel_text_address(info.ip)) | ||
41 | trace->entries[trace->nr_entries++] = info.ip; | ||
42 | } | ||
43 | } | ||
44 | |||
45 | |||
46 | /* | ||
47 | * Save stack-backtrace addresses into a stack_trace buffer. | ||
48 | */ | ||
49 | void save_stack_trace(struct stack_trace *trace) | ||
50 | { | ||
51 | dump_trace(current, trace); | ||
52 | if (trace->nr_entries < trace->max_entries) | ||
53 | trace->entries[trace->nr_entries++] = ULONG_MAX; | ||
54 | } | ||
55 | EXPORT_SYMBOL_GPL(save_stack_trace); | ||
56 | |||
57 | void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) | ||
58 | { | ||
59 | dump_trace(tsk, trace); | ||
60 | if (trace->nr_entries < trace->max_entries) | ||
61 | trace->entries[trace->nr_entries++] = ULONG_MAX; | ||
62 | } | ||
63 | EXPORT_SYMBOL_GPL(save_stack_trace_tsk); | ||