driver core: Make Kconfig text for DEBUG_TEST_DRIVER_REMOVE stronger
[cascardo/linux.git] / arch / s390 / kernel / stacktrace.c
1 /*
2  * Stack trace management functions
3  *
4  *  Copyright IBM Corp. 2006
5  *  Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
6  */
7
8 #include <linux/sched.h>
9 #include <linux/stacktrace.h>
10 #include <linux/kallsyms.h>
11 #include <linux/module.h>
12
13 static int __save_address(void *data, unsigned long address, int nosched)
14 {
15         struct stack_trace *trace = data;
16
17         if (nosched && in_sched_functions(address))
18                 return 0;
19         if (trace->skip > 0) {
20                 trace->skip--;
21                 return 0;
22         }
23         if (trace->nr_entries < trace->max_entries) {
24                 trace->entries[trace->nr_entries++] = address;
25                 return 0;
26         }
27         return 1;
28 }
29
30 static int save_address(void *data, unsigned long address)
31 {
32         return __save_address(data, address, 0);
33 }
34
35 static int save_address_nosched(void *data, unsigned long address)
36 {
37         return __save_address(data, address, 1);
38 }
39
40 void save_stack_trace(struct stack_trace *trace)
41 {
42         unsigned long sp;
43
44         sp = current_stack_pointer();
45         dump_trace(save_address, trace, NULL, sp);
46         if (trace->nr_entries < trace->max_entries)
47                 trace->entries[trace->nr_entries++] = ULONG_MAX;
48 }
49 EXPORT_SYMBOL_GPL(save_stack_trace);
50
51 void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
52 {
53         unsigned long sp;
54
55         sp = tsk->thread.ksp;
56         if (tsk == current)
57                 sp = current_stack_pointer();
58         dump_trace(save_address_nosched, trace, tsk, sp);
59         if (trace->nr_entries < trace->max_entries)
60                 trace->entries[trace->nr_entries++] = ULONG_MAX;
61 }
62 EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
63
64 void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace)
65 {
66         unsigned long sp;
67
68         sp = kernel_stack_pointer(regs);
69         dump_trace(save_address, trace, NULL, sp);
70         if (trace->nr_entries < trace->max_entries)
71                 trace->entries[trace->nr_entries++] = ULONG_MAX;
72 }
73 EXPORT_SYMBOL_GPL(save_stack_trace_regs);