xref: /openbmc/linux/arch/riscv/include/asm/ftrace.h (revision 9537603a)
110626c32SAlan Kao /* SPDX-License-Identifier: GPL-2.0 */
210626c32SAlan Kao /* Copyright (C) 2017 Andes Technology Corporation */
310626c32SAlan Kao 
46b57ba8eSZong Li #ifndef _ASM_RISCV_FTRACE_H
56b57ba8eSZong Li #define _ASM_RISCV_FTRACE_H
66b57ba8eSZong Li 
710626c32SAlan Kao /*
810626c32SAlan Kao  * The graph frame test is not possible if CONFIG_FRAME_POINTER is not enabled.
910626c32SAlan Kao  * Check arch/riscv/kernel/mcount.S for detail.
1010626c32SAlan Kao  */
1110626c32SAlan Kao #if defined(CONFIG_FUNCTION_GRAPH_TRACER) && defined(CONFIG_FRAME_POINTER)
1210626c32SAlan Kao #define HAVE_FUNCTION_GRAPH_FP_TEST
1310626c32SAlan Kao #endif
14aea4c671SAlan Kao #define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
15c15ac4fdSAlan Kao 
167ce04771SNathan Chancellor /*
177ce04771SNathan Chancellor  * Clang prior to 13 had "mcount" instead of "_mcount":
187ce04771SNathan Chancellor  * https://reviews.llvm.org/D98881
197ce04771SNathan Chancellor  */
207ce04771SNathan Chancellor #if defined(CONFIG_CC_IS_GCC) || CONFIG_CLANG_VERSION >= 130000
217ce04771SNathan Chancellor #define MCOUNT_NAME _mcount
227ce04771SNathan Chancellor #else
237ce04771SNathan Chancellor #define MCOUNT_NAME mcount
247ce04771SNathan Chancellor #endif
257ce04771SNathan Chancellor 
2671e736a7SAlan Kao #define ARCH_SUPPORTS_FTRACE_OPS 1
27c15ac4fdSAlan Kao #ifndef __ASSEMBLY__
28*9537603aSZong Li 
29*9537603aSZong Li extern void *return_address(unsigned int level);
30*9537603aSZong Li 
31*9537603aSZong Li #define ftrace_return_address(n) return_address(n)
32*9537603aSZong Li 
337ce04771SNathan Chancellor void MCOUNT_NAME(void);
ftrace_call_adjust(unsigned long addr)34c15ac4fdSAlan Kao static inline unsigned long ftrace_call_adjust(unsigned long addr)
35c15ac4fdSAlan Kao {
36c15ac4fdSAlan Kao 	return addr;
37c15ac4fdSAlan Kao }
38c15ac4fdSAlan Kao 
39a87e7d3eSAlexandre Ghiti /*
40a87e7d3eSAlexandre Ghiti  * Let's do like x86/arm64 and ignore the compat syscalls.
41a87e7d3eSAlexandre Ghiti  */
42a87e7d3eSAlexandre Ghiti #define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS
arch_trace_is_compat_syscall(struct pt_regs * regs)43a87e7d3eSAlexandre Ghiti static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs)
44a87e7d3eSAlexandre Ghiti {
45a87e7d3eSAlexandre Ghiti 	return is_compat_task();
46a87e7d3eSAlexandre Ghiti }
47a87e7d3eSAlexandre Ghiti 
48a87e7d3eSAlexandre Ghiti #define ARCH_HAS_SYSCALL_MATCH_SYM_NAME
arch_syscall_match_sym_name(const char * sym,const char * name)49a87e7d3eSAlexandre Ghiti static inline bool arch_syscall_match_sym_name(const char *sym,
50a87e7d3eSAlexandre Ghiti 					       const char *name)
51a87e7d3eSAlexandre Ghiti {
52a87e7d3eSAlexandre Ghiti 	/*
53a87e7d3eSAlexandre Ghiti 	 * Since all syscall functions have __riscv_ prefix, we must skip it.
54a87e7d3eSAlexandre Ghiti 	 * However, as we described above, we decided to ignore compat
55a87e7d3eSAlexandre Ghiti 	 * syscalls, so we don't care about __riscv_compat_ prefix here.
56a87e7d3eSAlexandre Ghiti 	 */
57a87e7d3eSAlexandre Ghiti 	return !strcmp(sym + 8, name);
58a87e7d3eSAlexandre Ghiti }
59a87e7d3eSAlexandre Ghiti 
60c15ac4fdSAlan Kao struct dyn_arch_ftrace {
61c15ac4fdSAlan Kao };
62c15ac4fdSAlan Kao #endif
63c15ac4fdSAlan Kao 
64c15ac4fdSAlan Kao #ifdef CONFIG_DYNAMIC_FTRACE
65c15ac4fdSAlan Kao /*
66c15ac4fdSAlan Kao  * A general call in RISC-V is a pair of insts:
67c15ac4fdSAlan Kao  * 1) auipc: setting high-20 pc-related bits to ra register
68c15ac4fdSAlan Kao  * 2) jalr: setting low-12 offset to ra, jump to ra, and set ra to
69c15ac4fdSAlan Kao  *          return address (original pc + 4)
70c15ac4fdSAlan Kao  *
716724a76cSGuo Ren  *<ftrace enable>:
726724a76cSGuo Ren  * 0: auipc  t0/ra, 0x?
736724a76cSGuo Ren  * 4: jalr   t0/ra, ?(t0/ra)
746724a76cSGuo Ren  *
756724a76cSGuo Ren  *<ftrace disable>:
766724a76cSGuo Ren  * 0: nop
776724a76cSGuo Ren  * 4: nop
786724a76cSGuo Ren  *
79c15ac4fdSAlan Kao  * Dynamic ftrace generates probes to call sites, so we must deal with
80c15ac4fdSAlan Kao  * both auipc and jalr at the same time.
81c15ac4fdSAlan Kao  */
82c15ac4fdSAlan Kao 
837ce04771SNathan Chancellor #define MCOUNT_ADDR		((unsigned long)MCOUNT_NAME)
84c15ac4fdSAlan Kao #define JALR_SIGN_MASK		(0x00000800)
85c15ac4fdSAlan Kao #define JALR_OFFSET_MASK	(0x00000fff)
86c15ac4fdSAlan Kao #define AUIPC_OFFSET_MASK	(0xfffff000)
87c15ac4fdSAlan Kao #define AUIPC_PAD		(0x00001000)
88c15ac4fdSAlan Kao #define JALR_SHIFT		20
896724a76cSGuo Ren #define JALR_RA			(0x000080e7)
906724a76cSGuo Ren #define AUIPC_RA		(0x00000097)
916724a76cSGuo Ren #define JALR_T0			(0x000282e7)
926724a76cSGuo Ren #define AUIPC_T0		(0x00000297)
93c15ac4fdSAlan Kao #define NOP4			(0x00000013)
94c15ac4fdSAlan Kao 
956724a76cSGuo Ren #define to_jalr_t0(offset)						\
966724a76cSGuo Ren 	(((offset & JALR_OFFSET_MASK) << JALR_SHIFT) | JALR_T0)
976724a76cSGuo Ren 
986724a76cSGuo Ren #define to_auipc_t0(offset)						\
996724a76cSGuo Ren 	((offset & JALR_SIGN_MASK) ?					\
1006724a76cSGuo Ren 	(((offset & AUIPC_OFFSET_MASK) + AUIPC_PAD) | AUIPC_T0) :	\
1016724a76cSGuo Ren 	((offset & AUIPC_OFFSET_MASK) | AUIPC_T0))
1026724a76cSGuo Ren 
1036724a76cSGuo Ren #define make_call_t0(caller, callee, call)				\
104c15ac4fdSAlan Kao do {									\
1056724a76cSGuo Ren 	unsigned int offset =						\
1066724a76cSGuo Ren 		(unsigned long) callee - (unsigned long) caller;	\
1076724a76cSGuo Ren 	call[0] = to_auipc_t0(offset);					\
1086724a76cSGuo Ren 	call[1] = to_jalr_t0(offset);					\
109c15ac4fdSAlan Kao } while (0)
110c15ac4fdSAlan Kao 
1116724a76cSGuo Ren #define to_jalr_ra(offset)						\
1126724a76cSGuo Ren 	(((offset & JALR_OFFSET_MASK) << JALR_SHIFT) | JALR_RA)
113c15ac4fdSAlan Kao 
1146724a76cSGuo Ren #define to_auipc_ra(offset)						\
115c15ac4fdSAlan Kao 	((offset & JALR_SIGN_MASK) ?					\
1166724a76cSGuo Ren 	(((offset & AUIPC_OFFSET_MASK) + AUIPC_PAD) | AUIPC_RA) :	\
1176724a76cSGuo Ren 	((offset & AUIPC_OFFSET_MASK) | AUIPC_RA))
1186724a76cSGuo Ren 
1196724a76cSGuo Ren #define make_call_ra(caller, callee, call)				\
1206724a76cSGuo Ren do {									\
1216724a76cSGuo Ren 	unsigned int offset =						\
1226724a76cSGuo Ren 		(unsigned long) callee - (unsigned long) caller;	\
1236724a76cSGuo Ren 	call[0] = to_auipc_ra(offset);					\
1246724a76cSGuo Ren 	call[1] = to_jalr_ra(offset);					\
1256724a76cSGuo Ren } while (0)
126c15ac4fdSAlan Kao 
127c15ac4fdSAlan Kao /*
128c15ac4fdSAlan Kao  * Let auipc+jalr be the basic *mcount unit*, so we make it 8 bytes here.
129c15ac4fdSAlan Kao  */
130c15ac4fdSAlan Kao #define MCOUNT_INSN_SIZE 8
13166d18dbdSPalmer Dabbelt 
13266d18dbdSPalmer Dabbelt #ifndef __ASSEMBLY__
13366d18dbdSPalmer Dabbelt struct dyn_ftrace;
13466d18dbdSPalmer Dabbelt int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
13566d18dbdSPalmer Dabbelt #define ftrace_init_nop ftrace_init_nop
13666d18dbdSPalmer Dabbelt #endif
13766d18dbdSPalmer Dabbelt 
1382a8db5ecSConor Dooley #endif /* CONFIG_DYNAMIC_FTRACE */
1396b57ba8eSZong Li 
140b97aec08SDonglin Peng #ifndef __ASSEMBLY__
141b97aec08SDonglin Peng #ifdef CONFIG_FUNCTION_GRAPH_TRACER
142b97aec08SDonglin Peng struct fgraph_ret_regs {
143b97aec08SDonglin Peng 	unsigned long a1;
144b97aec08SDonglin Peng 	unsigned long a0;
145b97aec08SDonglin Peng 	unsigned long s0;
146b97aec08SDonglin Peng 	unsigned long ra;
147b97aec08SDonglin Peng };
148b97aec08SDonglin Peng 
fgraph_ret_regs_return_value(struct fgraph_ret_regs * ret_regs)149b97aec08SDonglin Peng static inline unsigned long fgraph_ret_regs_return_value(struct fgraph_ret_regs *ret_regs)
150b97aec08SDonglin Peng {
151b97aec08SDonglin Peng 	return ret_regs->a0;
152b97aec08SDonglin Peng }
153b97aec08SDonglin Peng 
fgraph_ret_regs_frame_pointer(struct fgraph_ret_regs * ret_regs)154b97aec08SDonglin Peng static inline unsigned long fgraph_ret_regs_frame_pointer(struct fgraph_ret_regs *ret_regs)
155b97aec08SDonglin Peng {
156b97aec08SDonglin Peng 	return ret_regs->s0;
157b97aec08SDonglin Peng }
158b97aec08SDonglin Peng #endif /* ifdef CONFIG_FUNCTION_GRAPH_TRACER */
159b97aec08SDonglin Peng #endif
160b97aec08SDonglin Peng 
1616b57ba8eSZong Li #endif /* _ASM_RISCV_FTRACE_H */
162