stacktrace.c 1.0 KB

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