stacktrace.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*
  2. * Kernel and userspace stack tracing.
  3. *
  4. * This file is subject to the terms and conditions of the GNU General Public
  5. * License. See the file "COPYING" in the main directory of this archive
  6. * for more details.
  7. *
  8. * Copyright (C) 2001 - 2013 Tensilica Inc.
  9. * Copyright (C) 2015 Cadence Design Systems Inc.
  10. */
  11. #include <linux/export.h>
  12. #include <linux/sched.h>
  13. #include <linux/stacktrace.h>
  14. #include <asm/stacktrace.h>
  15. #include <asm/traps.h>
  16. #include <linux/uaccess.h>
  17. #if IS_ENABLED(CONFIG_OPROFILE) || IS_ENABLED(CONFIG_PERF_EVENTS)
  18. /* Address of common_exception_return, used to check the
  19. * transition from kernel to user space.
  20. */
  21. extern int common_exception_return;
  22. void xtensa_backtrace_user(struct pt_regs *regs, unsigned int depth,
  23. int (*ufn)(struct stackframe *frame, void *data),
  24. void *data)
  25. {
  26. unsigned long windowstart = regs->windowstart;
  27. unsigned long windowbase = regs->windowbase;
  28. unsigned long a0 = regs->areg[0];
  29. unsigned long a1 = regs->areg[1];
  30. unsigned long pc = regs->pc;
  31. struct stackframe frame;
  32. int index;
  33. if (!depth--)
  34. return;
  35. frame.pc = pc;
  36. frame.sp = a1;
  37. if (pc == 0 || pc >= TASK_SIZE || ufn(&frame, data))
  38. return;
  39. /* Two steps:
  40. *
  41. * 1. Look through the register window for the
  42. * previous PCs in the call trace.
  43. *
  44. * 2. Look on the stack.
  45. */
  46. /* Step 1. */
  47. /* Rotate WINDOWSTART to move the bit corresponding to
  48. * the current window to the bit #0.
  49. */
  50. windowstart = (windowstart << WSBITS | windowstart) >> windowbase;
  51. /* Look for bits that are set, they correspond to
  52. * valid windows.
  53. */
  54. for (index = WSBITS - 1; (index > 0) && depth; depth--, index--)
  55. if (windowstart & (1 << index)) {
  56. /* Get the PC from a0 and a1. */
  57. pc = MAKE_PC_FROM_RA(a0, pc);
  58. /* Read a0 and a1 from the
  59. * corresponding position in AREGs.
  60. */
  61. a0 = regs->areg[index * 4];
  62. a1 = regs->areg[index * 4 + 1];
  63. frame.pc = pc;
  64. frame.sp = a1;
  65. if (pc == 0 || pc >= TASK_SIZE || ufn(&frame, data))
  66. return;
  67. }
  68. /* Step 2. */
  69. /* We are done with the register window, we need to
  70. * look through the stack.
  71. */
  72. if (!depth)
  73. return;
  74. /* Start from the a1 register. */
  75. /* a1 = regs->areg[1]; */
  76. while (a0 != 0 && depth--) {
  77. pc = MAKE_PC_FROM_RA(a0, pc);
  78. /* Check if the region is OK to access. */
  79. if (!access_ok(VERIFY_READ, &SPILL_SLOT(a1, 0), 8))
  80. return;
  81. /* Copy a1, a0 from user space stack frame. */
  82. if (__get_user(a0, &SPILL_SLOT(a1, 0)) ||
  83. __get_user(a1, &SPILL_SLOT(a1, 1)))
  84. return;
  85. frame.pc = pc;
  86. frame.sp = a1;
  87. if (pc == 0 || pc >= TASK_SIZE || ufn(&frame, data))
  88. return;
  89. }
  90. }
  91. EXPORT_SYMBOL(xtensa_backtrace_user);
  92. void xtensa_backtrace_kernel(struct pt_regs *regs, unsigned int depth,
  93. int (*kfn)(struct stackframe *frame, void *data),
  94. int (*ufn)(struct stackframe *frame, void *data),
  95. void *data)
  96. {
  97. unsigned long pc = regs->depc > VALID_DOUBLE_EXCEPTION_ADDRESS ?
  98. regs->depc : regs->pc;
  99. unsigned long sp_start, sp_end;
  100. unsigned long a0 = regs->areg[0];
  101. unsigned long a1 = regs->areg[1];
  102. sp_start = a1 & ~(THREAD_SIZE - 1);
  103. sp_end = sp_start + THREAD_SIZE;
  104. /* Spill the register window to the stack first. */
  105. spill_registers();
  106. /* Read the stack frames one by one and create the PC
  107. * from the a0 and a1 registers saved there.
  108. */
  109. while (a1 > sp_start && a1 < sp_end && depth--) {
  110. struct stackframe frame;
  111. frame.pc = pc;
  112. frame.sp = a1;
  113. if (kernel_text_address(pc) && kfn(&frame, data))
  114. return;
  115. if (pc == (unsigned long)&common_exception_return) {
  116. regs = (struct pt_regs *)a1;
  117. if (user_mode(regs)) {
  118. if (ufn == NULL)
  119. return;
  120. xtensa_backtrace_user(regs, depth, ufn, data);
  121. return;
  122. }
  123. a0 = regs->areg[0];
  124. a1 = regs->areg[1];
  125. continue;
  126. }
  127. sp_start = a1;
  128. pc = MAKE_PC_FROM_RA(a0, pc);
  129. a0 = SPILL_SLOT(a1, 0);
  130. a1 = SPILL_SLOT(a1, 1);
  131. }
  132. }
  133. EXPORT_SYMBOL(xtensa_backtrace_kernel);
  134. #endif
  135. void walk_stackframe(unsigned long *sp,
  136. int (*fn)(struct stackframe *frame, void *data),
  137. void *data)
  138. {
  139. unsigned long a0, a1;
  140. unsigned long sp_end;
  141. a1 = (unsigned long)sp;
  142. sp_end = ALIGN(a1, THREAD_SIZE);
  143. spill_registers();
  144. while (a1 < sp_end) {
  145. struct stackframe frame;
  146. sp = (unsigned long *)a1;
  147. a0 = SPILL_SLOT(a1, 0);
  148. a1 = SPILL_SLOT(a1, 1);
  149. if (a1 <= (unsigned long)sp)
  150. break;
  151. frame.pc = MAKE_PC_FROM_RA(a0, a1);
  152. frame.sp = a1;
  153. if (fn(&frame, data))
  154. return;
  155. }
  156. }
  157. #ifdef CONFIG_STACKTRACE
  158. struct stack_trace_data {
  159. struct stack_trace *trace;
  160. unsigned skip;
  161. };
  162. static int stack_trace_cb(struct stackframe *frame, void *data)
  163. {
  164. struct stack_trace_data *trace_data = data;
  165. struct stack_trace *trace = trace_data->trace;
  166. if (trace_data->skip) {
  167. --trace_data->skip;
  168. return 0;
  169. }
  170. if (!kernel_text_address(frame->pc))
  171. return 0;
  172. trace->entries[trace->nr_entries++] = frame->pc;
  173. return trace->nr_entries >= trace->max_entries;
  174. }
  175. void save_stack_trace_tsk(struct task_struct *task, struct stack_trace *trace)
  176. {
  177. struct stack_trace_data trace_data = {
  178. .trace = trace,
  179. .skip = trace->skip,
  180. };
  181. walk_stackframe(stack_pointer(task), stack_trace_cb, &trace_data);
  182. }
  183. EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
  184. void save_stack_trace(struct stack_trace *trace)
  185. {
  186. save_stack_trace_tsk(current, trace);
  187. }
  188. EXPORT_SYMBOL_GPL(save_stack_trace);
  189. #endif
  190. #ifdef CONFIG_FRAME_POINTER
  191. struct return_addr_data {
  192. unsigned long addr;
  193. unsigned skip;
  194. };
  195. static int return_address_cb(struct stackframe *frame, void *data)
  196. {
  197. struct return_addr_data *r = data;
  198. if (r->skip) {
  199. --r->skip;
  200. return 0;
  201. }
  202. if (!kernel_text_address(frame->pc))
  203. return 0;
  204. r->addr = frame->pc;
  205. return 1;
  206. }
  207. /*
  208. * level == 0 is for the return address from the caller of this function,
  209. * not from this function itself.
  210. */
  211. unsigned long return_address(unsigned level)
  212. {
  213. struct return_addr_data r = {
  214. .skip = level,
  215. };
  216. walk_stackframe(stack_pointer(NULL), return_address_cb, &r);
  217. return r.addr;
  218. }
  219. EXPORT_SYMBOL(return_address);
  220. #endif