xref: /openbmc/linux/arch/x86/kernel/stacktrace.c (revision 250c22777fe1ccd7ac588579a6c16db4c0161cc5)
1*250c2277SThomas Gleixner /*
2*250c2277SThomas Gleixner  * arch/x86_64/kernel/stacktrace.c
3*250c2277SThomas Gleixner  *
4*250c2277SThomas Gleixner  * Stack trace management functions
5*250c2277SThomas Gleixner  *
6*250c2277SThomas Gleixner  *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
7*250c2277SThomas Gleixner  */
8*250c2277SThomas Gleixner #include <linux/sched.h>
9*250c2277SThomas Gleixner #include <linux/stacktrace.h>
10*250c2277SThomas Gleixner #include <linux/module.h>
11*250c2277SThomas Gleixner #include <asm/stacktrace.h>
12*250c2277SThomas Gleixner 
13*250c2277SThomas Gleixner static void save_stack_warning(void *data, char *msg)
14*250c2277SThomas Gleixner {
15*250c2277SThomas Gleixner }
16*250c2277SThomas Gleixner 
17*250c2277SThomas Gleixner static void
18*250c2277SThomas Gleixner save_stack_warning_symbol(void *data, char *msg, unsigned long symbol)
19*250c2277SThomas Gleixner {
20*250c2277SThomas Gleixner }
21*250c2277SThomas Gleixner 
22*250c2277SThomas Gleixner static int save_stack_stack(void *data, char *name)
23*250c2277SThomas Gleixner {
24*250c2277SThomas Gleixner 	return -1;
25*250c2277SThomas Gleixner }
26*250c2277SThomas Gleixner 
27*250c2277SThomas Gleixner static void save_stack_address(void *data, unsigned long addr)
28*250c2277SThomas Gleixner {
29*250c2277SThomas Gleixner 	struct stack_trace *trace = (struct stack_trace *)data;
30*250c2277SThomas Gleixner 	if (trace->skip > 0) {
31*250c2277SThomas Gleixner 		trace->skip--;
32*250c2277SThomas Gleixner 		return;
33*250c2277SThomas Gleixner 	}
34*250c2277SThomas Gleixner 	if (trace->nr_entries < trace->max_entries)
35*250c2277SThomas Gleixner 		trace->entries[trace->nr_entries++] = addr;
36*250c2277SThomas Gleixner }
37*250c2277SThomas Gleixner 
38*250c2277SThomas Gleixner static struct stacktrace_ops save_stack_ops = {
39*250c2277SThomas Gleixner 	.warning = save_stack_warning,
40*250c2277SThomas Gleixner 	.warning_symbol = save_stack_warning_symbol,
41*250c2277SThomas Gleixner 	.stack = save_stack_stack,
42*250c2277SThomas Gleixner 	.address = save_stack_address,
43*250c2277SThomas Gleixner };
44*250c2277SThomas Gleixner 
45*250c2277SThomas Gleixner /*
46*250c2277SThomas Gleixner  * Save stack-backtrace addresses into a stack_trace buffer.
47*250c2277SThomas Gleixner  */
48*250c2277SThomas Gleixner void save_stack_trace(struct stack_trace *trace)
49*250c2277SThomas Gleixner {
50*250c2277SThomas Gleixner 	dump_trace(current, NULL, NULL, &save_stack_ops, trace);
51*250c2277SThomas Gleixner 	if (trace->nr_entries < trace->max_entries)
52*250c2277SThomas Gleixner 		trace->entries[trace->nr_entries++] = ULONG_MAX;
53*250c2277SThomas Gleixner }
54*250c2277SThomas Gleixner EXPORT_SYMBOL(save_stack_trace);
55