callchain_32.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Performance counter callchain support - powerpc architecture code
  4. *
  5. * Copyright © 2009 Paul Mackerras, IBM Corporation.
  6. */
  7. #include <linux/kernel.h>
  8. #include <linux/sched.h>
  9. #include <linux/perf_event.h>
  10. #include <linux/percpu.h>
  11. #include <linux/uaccess.h>
  12. #include <linux/mm.h>
  13. #include <asm/ptrace.h>
  14. #include <asm/sigcontext.h>
  15. #include <asm/ucontext.h>
  16. #include <asm/vdso.h>
  17. #include <asm/pte-walk.h>
  18. #include "callchain.h"
  19. #ifdef CONFIG_PPC64
  20. #include <asm/syscalls_32.h>
  21. #else /* CONFIG_PPC64 */
  22. #define __SIGNAL_FRAMESIZE32 __SIGNAL_FRAMESIZE
  23. #define sigcontext32 sigcontext
  24. #define mcontext32 mcontext
  25. #define ucontext32 ucontext
  26. #define compat_siginfo_t struct siginfo
  27. #endif /* CONFIG_PPC64 */
  28. static int read_user_stack_32(const unsigned int __user *ptr, unsigned int *ret)
  29. {
  30. return __read_user_stack(ptr, ret, sizeof(*ret));
  31. }
  32. /*
  33. * Layout for non-RT signal frames
  34. */
  35. struct signal_frame_32 {
  36. char dummy[__SIGNAL_FRAMESIZE32];
  37. struct sigcontext32 sctx;
  38. struct mcontext32 mctx;
  39. int abigap[56];
  40. };
  41. /*
  42. * Layout for RT signal frames
  43. */
  44. struct rt_signal_frame_32 {
  45. char dummy[__SIGNAL_FRAMESIZE32 + 16];
  46. compat_siginfo_t info;
  47. struct ucontext32 uc;
  48. int abigap[56];
  49. };
  50. static int is_sigreturn_32_address(unsigned int nip, unsigned int fp)
  51. {
  52. if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad))
  53. return 1;
  54. if (current->mm->context.vdso &&
  55. nip == VDSO32_SYMBOL(current->mm->context.vdso, sigtramp32))
  56. return 1;
  57. return 0;
  58. }
  59. static int is_rt_sigreturn_32_address(unsigned int nip, unsigned int fp)
  60. {
  61. if (nip == fp + offsetof(struct rt_signal_frame_32,
  62. uc.uc_mcontext.mc_pad))
  63. return 1;
  64. if (current->mm->context.vdso &&
  65. nip == VDSO32_SYMBOL(current->mm->context.vdso, sigtramp_rt32))
  66. return 1;
  67. return 0;
  68. }
  69. static int sane_signal_32_frame(unsigned int sp)
  70. {
  71. struct signal_frame_32 __user *sf;
  72. unsigned int regs;
  73. sf = (struct signal_frame_32 __user *) (unsigned long) sp;
  74. if (read_user_stack_32((unsigned int __user *) &sf->sctx.regs, &regs))
  75. return 0;
  76. return regs == (unsigned long) &sf->mctx;
  77. }
  78. static int sane_rt_signal_32_frame(unsigned int sp)
  79. {
  80. struct rt_signal_frame_32 __user *sf;
  81. unsigned int regs;
  82. sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp;
  83. if (read_user_stack_32((unsigned int __user *) &sf->uc.uc_regs, &regs))
  84. return 0;
  85. return regs == (unsigned long) &sf->uc.uc_mcontext;
  86. }
  87. static unsigned int __user *signal_frame_32_regs(unsigned int sp,
  88. unsigned int next_sp, unsigned int next_ip)
  89. {
  90. struct mcontext32 __user *mctx = NULL;
  91. struct signal_frame_32 __user *sf;
  92. struct rt_signal_frame_32 __user *rt_sf;
  93. /*
  94. * Note: the next_sp - sp >= signal frame size check
  95. * is true when next_sp < sp, for example, when
  96. * transitioning from an alternate signal stack to the
  97. * normal stack.
  98. */
  99. if (next_sp - sp >= sizeof(struct signal_frame_32) &&
  100. is_sigreturn_32_address(next_ip, sp) &&
  101. sane_signal_32_frame(sp)) {
  102. sf = (struct signal_frame_32 __user *) (unsigned long) sp;
  103. mctx = &sf->mctx;
  104. }
  105. if (!mctx && next_sp - sp >= sizeof(struct rt_signal_frame_32) &&
  106. is_rt_sigreturn_32_address(next_ip, sp) &&
  107. sane_rt_signal_32_frame(sp)) {
  108. rt_sf = (struct rt_signal_frame_32 __user *) (unsigned long) sp;
  109. mctx = &rt_sf->uc.uc_mcontext;
  110. }
  111. if (!mctx)
  112. return NULL;
  113. return mctx->mc_gregs;
  114. }
  115. void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
  116. struct pt_regs *regs)
  117. {
  118. unsigned int sp, next_sp;
  119. unsigned int next_ip;
  120. unsigned int lr;
  121. long level = 0;
  122. unsigned int __user *fp, *uregs;
  123. next_ip = perf_instruction_pointer(regs);
  124. lr = regs->link;
  125. sp = regs->gpr[1];
  126. perf_callchain_store(entry, next_ip);
  127. while (entry->nr < entry->max_stack) {
  128. fp = (unsigned int __user *) (unsigned long) sp;
  129. if (invalid_user_sp(sp) || read_user_stack_32(fp, &next_sp))
  130. return;
  131. if (level > 0 && read_user_stack_32(&fp[1], &next_ip))
  132. return;
  133. uregs = signal_frame_32_regs(sp, next_sp, next_ip);
  134. if (!uregs && level <= 1)
  135. uregs = signal_frame_32_regs(sp, next_sp, lr);
  136. if (uregs) {
  137. /*
  138. * This looks like an signal frame, so restart
  139. * the stack trace with the values in it.
  140. */
  141. if (read_user_stack_32(&uregs[PT_NIP], &next_ip) ||
  142. read_user_stack_32(&uregs[PT_LNK], &lr) ||
  143. read_user_stack_32(&uregs[PT_R1], &sp))
  144. return;
  145. level = 0;
  146. perf_callchain_store_context(entry, PERF_CONTEXT_USER);
  147. perf_callchain_store(entry, next_ip);
  148. continue;
  149. }
  150. if (level == 0)
  151. next_ip = lr;
  152. perf_callchain_store(entry, next_ip);
  153. ++level;
  154. sp = next_sp;
  155. }
  156. }