]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - arch/powerpc/kernel/stacktrace.c
UBUNTU: Ubuntu-4.10.0-37.41
[mirror_ubuntu-zesty-kernel.git] / arch / powerpc / kernel / stacktrace.c
CommitLineData
fd3e0bbc
CH
1/*
2 * Stack trace utility
3 *
4 * Copyright 2008 Christoph Hellwig, IBM Corp.
5 *
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12
4b16f8e2 13#include <linux/export.h>
fd3e0bbc
CH
14#include <linux/sched.h>
15#include <linux/stacktrace.h>
16#include <asm/ptrace.h>
01f4b8b8 17#include <asm/processor.h>
fd3e0bbc
CH
18
19/*
20 * Save stack-backtrace addresses into a stack_trace buffer.
21 */
01f4b8b8
AB
22static void save_context_stack(struct stack_trace *trace, unsigned long sp,
23 struct task_struct *tsk, int savesched)
fd3e0bbc 24{
fd3e0bbc
CH
25 for (;;) {
26 unsigned long *stack = (unsigned long *) sp;
27 unsigned long newsp, ip;
28
01f4b8b8 29 if (!validate_sp(sp, tsk, STACK_FRAME_OVERHEAD))
fd3e0bbc
CH
30 return;
31
32 newsp = stack[0];
33 ip = stack[STACK_FRAME_LR_SAVE];
34
01f4b8b8
AB
35 if (savesched || !in_sched_functions(ip)) {
36 if (!trace->skip)
37 trace->entries[trace->nr_entries++] = ip;
38 else
39 trace->skip--;
40 }
fd3e0bbc
CH
41
42 if (trace->nr_entries >= trace->max_entries)
43 return;
44
45 sp = newsp;
46 }
47}
01f4b8b8
AB
48
49void save_stack_trace(struct stack_trace *trace)
50{
51 unsigned long sp;
52
acf620ec 53 sp = current_stack_pointer();
01f4b8b8
AB
54
55 save_context_stack(trace, sp, current, 1);
56}
57EXPORT_SYMBOL_GPL(save_stack_trace);
58
59void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
60{
6fdc9f50 61 save_context_stack(trace, tsk->thread.ksp, tsk, 0);
01f4b8b8
AB
62}
63EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
35de3b1a
SR
64
65void
66save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace)
67{
68 save_context_stack(trace, regs->gpr[1], current, 0);
69}
70EXPORT_SYMBOL_GPL(save_stack_trace_regs);