ftrace.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * arch/arm64/include/asm/ftrace.h
  4. *
  5. * Copyright (C) 2013 Linaro Limited
  6. * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
  7. */
  8. #ifndef __ASM_FTRACE_H
  9. #define __ASM_FTRACE_H
  10. #include <asm/insn.h>
  11. #define HAVE_FUNCTION_GRAPH_FP_TEST
  12. #ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
  13. #define ARCH_SUPPORTS_FTRACE_OPS 1
  14. #else
  15. #define MCOUNT_ADDR ((unsigned long)_mcount)
  16. #endif
  17. /* The BL at the callsite's adjusted rec->ip */
  18. #define MCOUNT_INSN_SIZE AARCH64_INSN_SIZE
  19. #define FTRACE_PLT_IDX 0
  20. #define NR_FTRACE_PLTS 1
  21. /*
  22. * Currently, gcc tends to save the link register after the local variables
  23. * on the stack. This causes the max stack tracer to report the function
  24. * frame sizes for the wrong functions. By defining
  25. * ARCH_FTRACE_SHIFT_STACK_TRACER, it will tell the stack tracer to expect
  26. * to find the return address on the stack after the local variables have
  27. * been set up.
  28. *
  29. * Note, this may change in the future, and we will need to deal with that
  30. * if it were to happen.
  31. */
  32. #define ARCH_FTRACE_SHIFT_STACK_TRACER 1
  33. #ifndef __ASSEMBLER__
  34. #include <linux/compat.h>
  35. extern void _mcount(unsigned long);
  36. extern void *return_address(unsigned int);
  37. struct dyn_arch_ftrace {
  38. /* No extra data needed for arm64 */
  39. };
  40. extern unsigned long ftrace_graph_call;
  41. extern void return_to_handler(void);
  42. unsigned long ftrace_call_adjust(unsigned long addr);
  43. unsigned long arch_ftrace_get_symaddr(unsigned long fentry_ip);
  44. #define ftrace_get_symaddr(fentry_ip) arch_ftrace_get_symaddr(fentry_ip)
  45. #ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
  46. #define HAVE_ARCH_FTRACE_REGS
  47. struct dyn_ftrace;
  48. struct ftrace_ops;
  49. struct ftrace_regs;
  50. #define arch_ftrace_regs(fregs) ((struct __arch_ftrace_regs *)(fregs))
  51. #define arch_ftrace_get_regs(regs) NULL
  52. /*
  53. * Note: sizeof(struct ftrace_regs) must be a multiple of 16 to ensure correct
  54. * stack alignment
  55. */
  56. struct __arch_ftrace_regs {
  57. /* x0 - x8 */
  58. unsigned long regs[9];
  59. #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
  60. unsigned long direct_tramp;
  61. #else
  62. unsigned long __unused;
  63. #endif
  64. unsigned long fp;
  65. unsigned long lr;
  66. unsigned long sp;
  67. unsigned long pc;
  68. };
  69. static __always_inline unsigned long
  70. ftrace_regs_get_instruction_pointer(const struct ftrace_regs *fregs)
  71. {
  72. return arch_ftrace_regs(fregs)->pc;
  73. }
  74. static __always_inline void
  75. ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs,
  76. unsigned long pc)
  77. {
  78. arch_ftrace_regs(fregs)->pc = pc;
  79. }
  80. static __always_inline unsigned long
  81. ftrace_regs_get_stack_pointer(const struct ftrace_regs *fregs)
  82. {
  83. return arch_ftrace_regs(fregs)->sp;
  84. }
  85. static __always_inline unsigned long
  86. ftrace_regs_get_argument(struct ftrace_regs *fregs, unsigned int n)
  87. {
  88. if (n < 8)
  89. return arch_ftrace_regs(fregs)->regs[n];
  90. return 0;
  91. }
  92. static __always_inline unsigned long
  93. ftrace_regs_get_return_value(const struct ftrace_regs *fregs)
  94. {
  95. return arch_ftrace_regs(fregs)->regs[0];
  96. }
  97. static __always_inline void
  98. ftrace_regs_set_return_value(struct ftrace_regs *fregs,
  99. unsigned long ret)
  100. {
  101. arch_ftrace_regs(fregs)->regs[0] = ret;
  102. }
  103. static __always_inline void
  104. ftrace_override_function_with_return(struct ftrace_regs *fregs)
  105. {
  106. arch_ftrace_regs(fregs)->pc = arch_ftrace_regs(fregs)->lr;
  107. }
  108. static __always_inline unsigned long
  109. ftrace_regs_get_frame_pointer(const struct ftrace_regs *fregs)
  110. {
  111. return arch_ftrace_regs(fregs)->fp;
  112. }
  113. static __always_inline unsigned long
  114. ftrace_regs_get_return_address(const struct ftrace_regs *fregs)
  115. {
  116. return arch_ftrace_regs(fregs)->lr;
  117. }
  118. static __always_inline struct pt_regs *
  119. ftrace_partial_regs(const struct ftrace_regs *fregs, struct pt_regs *regs)
  120. {
  121. struct __arch_ftrace_regs *afregs = arch_ftrace_regs(fregs);
  122. memcpy(regs->regs, afregs->regs, sizeof(afregs->regs));
  123. regs->sp = afregs->sp;
  124. regs->pc = afregs->pc;
  125. regs->regs[29] = afregs->fp;
  126. regs->regs[30] = afregs->lr;
  127. regs->pstate = PSR_MODE_EL1h;
  128. return regs;
  129. }
  130. #define arch_ftrace_fill_perf_regs(fregs, _regs) do { \
  131. (_regs)->pc = arch_ftrace_regs(fregs)->pc; \
  132. (_regs)->regs[29] = arch_ftrace_regs(fregs)->fp; \
  133. (_regs)->sp = arch_ftrace_regs(fregs)->sp; \
  134. (_regs)->pstate = PSR_MODE_EL1h; \
  135. } while (0)
  136. int ftrace_regs_query_register_offset(const char *name);
  137. int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
  138. #define ftrace_init_nop ftrace_init_nop
  139. void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
  140. struct ftrace_ops *op, struct ftrace_regs *fregs);
  141. #define ftrace_graph_func ftrace_graph_func
  142. #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
  143. static inline void arch_ftrace_set_direct_caller(struct ftrace_regs *fregs,
  144. unsigned long addr)
  145. {
  146. /*
  147. * The ftrace trampoline will return to this address instead of the
  148. * instrumented function.
  149. */
  150. arch_ftrace_regs(fregs)->direct_tramp = addr;
  151. }
  152. #endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
  153. #endif
  154. #define ftrace_return_address(n) return_address(n)
  155. /*
  156. * Because AArch32 mode does not share the same syscall table with AArch64,
  157. * tracing compat syscalls may result in reporting bogus syscalls or even
  158. * hang-up, so just do not trace them.
  159. * See kernel/trace/trace_syscalls.c
  160. *
  161. * x86 code says:
  162. * If the user really wants these, then they should use the
  163. * raw syscall tracepoints with filtering.
  164. */
  165. #define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS
  166. static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs)
  167. {
  168. return is_compat_task();
  169. }
  170. #define ARCH_HAS_SYSCALL_MATCH_SYM_NAME
  171. static inline bool arch_syscall_match_sym_name(const char *sym,
  172. const char *name)
  173. {
  174. /*
  175. * Since all syscall functions have __arm64_ prefix, we must skip it.
  176. * However, as we described above, we decided to ignore compat
  177. * syscalls, so we don't care about __arm64_compat_ prefix here.
  178. */
  179. return !strcmp(sym + 8, name);
  180. }
  181. #endif /* ifndef __ASSEMBLER__ */
  182. #ifndef __ASSEMBLER__
  183. #ifdef CONFIG_FUNCTION_GRAPH_TRACER
  184. void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent,
  185. unsigned long frame_pointer);
  186. #endif /* ifdef CONFIG_FUNCTION_GRAPH_TRACER */
  187. #endif
  188. #endif /* __ASM_FTRACE_H */