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