• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  // SPDX-License-Identifier: GPL-2.0
2  // Copyright (C) 2005-2017 Andes Technology Corporation
3  
4  #include <linux/sched/debug.h>
5  #include <linux/sched/task_stack.h>
6  #include <linux/stacktrace.h>
7  #include <linux/ftrace.h>
8  
save_stack_trace(struct stack_trace * trace)9  void save_stack_trace(struct stack_trace *trace)
10  {
11  	save_stack_trace_tsk(current, trace);
12  }
13  EXPORT_SYMBOL_GPL(save_stack_trace);
14  
save_stack_trace_tsk(struct task_struct * tsk,struct stack_trace * trace)15  void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
16  {
17  	unsigned long *fpn;
18  	int skip = trace->skip;
19  	int savesched;
20  	int graph_idx = 0;
21  
22  	if (tsk == current) {
23  		__asm__ __volatile__("\tori\t%0, $fp, #0\n":"=r"(fpn));
24  		savesched = 1;
25  	} else {
26  		fpn = (unsigned long *)thread_saved_fp(tsk);
27  		savesched = 0;
28  	}
29  
30  	while (!kstack_end(fpn) && !((unsigned long)fpn & 0x3)
31  	       && (fpn >= (unsigned long *)TASK_SIZE)) {
32  		unsigned long lpp, fpp;
33  
34  		lpp = fpn[LP_OFFSET];
35  		fpp = fpn[FP_OFFSET];
36  		if (!__kernel_text_address(lpp))
37  			break;
38  		else
39  			lpp = ftrace_graph_ret_addr(tsk, &graph_idx, lpp, NULL);
40  
41  		if (savesched || !in_sched_functions(lpp)) {
42  			if (skip) {
43  				skip--;
44  			} else {
45  				trace->entries[trace->nr_entries++] = lpp;
46  				if (trace->nr_entries >= trace->max_entries)
47  					break;
48  			}
49  		}
50  		fpn = (unsigned long *)fpp;
51  	}
52  }
53  EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
54