aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/stacktrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/stacktrace.c')
-rw-r--r--arch/powerpc/kernel/stacktrace.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c
index 962944038430..071bee3ec749 100644
--- a/arch/powerpc/kernel/stacktrace.c
+++ b/arch/powerpc/kernel/stacktrace.c
@@ -10,33 +10,35 @@
10 * 2 of the License, or (at your option) any later version. 10 * 2 of the License, or (at your option) any later version.
11 */ 11 */
12 12
13#include <linux/module.h>
13#include <linux/sched.h> 14#include <linux/sched.h>
14#include <linux/stacktrace.h> 15#include <linux/stacktrace.h>
16#include <linux/module.h>
15#include <asm/ptrace.h> 17#include <asm/ptrace.h>
18#include <asm/processor.h>
16 19
17/* 20/*
18 * Save stack-backtrace addresses into a stack_trace buffer. 21 * Save stack-backtrace addresses into a stack_trace buffer.
19 */ 22 */
20void save_stack_trace(struct stack_trace *trace) 23static void save_context_stack(struct stack_trace *trace, unsigned long sp,
24 struct task_struct *tsk, int savesched)
21{ 25{
22 unsigned long sp;
23
24 asm("mr %0,1" : "=r" (sp));
25
26 for (;;) { 26 for (;;) {
27 unsigned long *stack = (unsigned long *) sp; 27 unsigned long *stack = (unsigned long *) sp;
28 unsigned long newsp, ip; 28 unsigned long newsp, ip;
29 29
30 if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD)) 30 if (!validate_sp(sp, tsk, STACK_FRAME_OVERHEAD))
31 return; 31 return;
32 32
33 newsp = stack[0]; 33 newsp = stack[0];
34 ip = stack[STACK_FRAME_LR_SAVE]; 34 ip = stack[STACK_FRAME_LR_SAVE];
35 35
36 if (!trace->skip) 36 if (savesched || !in_sched_functions(ip)) {
37 trace->entries[trace->nr_entries++] = ip; 37 if (!trace->skip)
38 else 38 trace->entries[trace->nr_entries++] = ip;
39 trace->skip--; 39 else
40 trace->skip--;
41 }
40 42
41 if (trace->nr_entries >= trace->max_entries) 43 if (trace->nr_entries >= trace->max_entries)
42 return; 44 return;
@@ -44,3 +46,19 @@ void save_stack_trace(struct stack_trace *trace)
44 sp = newsp; 46 sp = newsp;
45 } 47 }
46} 48}
49
50void save_stack_trace(struct stack_trace *trace)
51{
52 unsigned long sp;
53
54 asm("mr %0,1" : "=r" (sp));
55
56 save_context_stack(trace, sp, current, 1);
57}
58EXPORT_SYMBOL_GPL(save_stack_trace);
59
60void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
61{
62 save_context_stack(trace, tsk->thread.regs->gpr[1], tsk, 0);
63}
64EXPORT_SYMBOL_GPL(save_stack_trace_tsk);