xref: /OK3568_Linux_fs/kernel/arch/powerpc/include/asm/ftrace.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun #ifndef _ASM_POWERPC_FTRACE
3*4882a593Smuzhiyun #define _ASM_POWERPC_FTRACE
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #include <asm/types.h>
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #ifdef CONFIG_FUNCTION_TRACER
8*4882a593Smuzhiyun #define MCOUNT_ADDR		((unsigned long)(_mcount))
9*4882a593Smuzhiyun #define MCOUNT_INSN_SIZE	4 /* sizeof mcount call */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #ifdef __ASSEMBLY__
14*4882a593Smuzhiyun 
15*4882a593Smuzhiyun /* Based off of objdump optput from glibc */
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #define MCOUNT_SAVE_FRAME			\
18*4882a593Smuzhiyun 	stwu	r1,-48(r1);			\
19*4882a593Smuzhiyun 	stw	r3, 12(r1);			\
20*4882a593Smuzhiyun 	stw	r4, 16(r1);			\
21*4882a593Smuzhiyun 	stw	r5, 20(r1);			\
22*4882a593Smuzhiyun 	stw	r6, 24(r1);			\
23*4882a593Smuzhiyun 	mflr	r3;				\
24*4882a593Smuzhiyun 	lwz	r4, 52(r1);			\
25*4882a593Smuzhiyun 	mfcr	r5;				\
26*4882a593Smuzhiyun 	stw	r7, 28(r1);			\
27*4882a593Smuzhiyun 	stw	r8, 32(r1);			\
28*4882a593Smuzhiyun 	stw	r9, 36(r1);			\
29*4882a593Smuzhiyun 	stw	r10,40(r1);			\
30*4882a593Smuzhiyun 	stw	r3, 44(r1);			\
31*4882a593Smuzhiyun 	stw	r5, 8(r1)
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #define MCOUNT_RESTORE_FRAME			\
34*4882a593Smuzhiyun 	lwz	r6, 8(r1);			\
35*4882a593Smuzhiyun 	lwz	r0, 44(r1);			\
36*4882a593Smuzhiyun 	lwz	r3, 12(r1);			\
37*4882a593Smuzhiyun 	mtctr	r0;				\
38*4882a593Smuzhiyun 	lwz	r4, 16(r1);			\
39*4882a593Smuzhiyun 	mtcr	r6;				\
40*4882a593Smuzhiyun 	lwz	r5, 20(r1);			\
41*4882a593Smuzhiyun 	lwz	r6, 24(r1);			\
42*4882a593Smuzhiyun 	lwz	r0, 52(r1);			\
43*4882a593Smuzhiyun 	lwz	r7, 28(r1);			\
44*4882a593Smuzhiyun 	lwz	r8, 32(r1);			\
45*4882a593Smuzhiyun 	mtlr	r0;				\
46*4882a593Smuzhiyun 	lwz	r9, 36(r1);			\
47*4882a593Smuzhiyun 	lwz	r10,40(r1);			\
48*4882a593Smuzhiyun 	addi	r1, r1, 48
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun #else /* !__ASSEMBLY__ */
51*4882a593Smuzhiyun extern void _mcount(void);
52*4882a593Smuzhiyun 
ftrace_call_adjust(unsigned long addr)53*4882a593Smuzhiyun static inline unsigned long ftrace_call_adjust(unsigned long addr)
54*4882a593Smuzhiyun {
55*4882a593Smuzhiyun        /* reloction of mcount call site is the same as the address */
56*4882a593Smuzhiyun        return addr;
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun struct dyn_arch_ftrace {
60*4882a593Smuzhiyun 	struct module *mod;
61*4882a593Smuzhiyun };
62*4882a593Smuzhiyun #endif /* __ASSEMBLY__ */
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
65*4882a593Smuzhiyun #define ARCH_SUPPORTS_FTRACE_OPS 1
66*4882a593Smuzhiyun #endif
67*4882a593Smuzhiyun #endif /* CONFIG_FUNCTION_TRACER */
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun #ifndef __ASSEMBLY__
70*4882a593Smuzhiyun #ifdef CONFIG_FTRACE_SYSCALLS
71*4882a593Smuzhiyun /*
72*4882a593Smuzhiyun  * Some syscall entry functions on powerpc start with "ppc_" (fork and clone,
73*4882a593Smuzhiyun  * for instance) or ppc32_/ppc64_. We should also match the sys_ variant with
74*4882a593Smuzhiyun  * those.
75*4882a593Smuzhiyun  */
76*4882a593Smuzhiyun #define ARCH_HAS_SYSCALL_MATCH_SYM_NAME
77*4882a593Smuzhiyun #ifdef PPC64_ELF_ABI_v1
arch_syscall_match_sym_name(const char * sym,const char * name)78*4882a593Smuzhiyun static inline bool arch_syscall_match_sym_name(const char *sym, const char *name)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun 	/* We need to skip past the initial dot, and the __se_sys alias */
81*4882a593Smuzhiyun 	return !strcmp(sym + 1, name) ||
82*4882a593Smuzhiyun 		(!strncmp(sym, ".__se_sys", 9) && !strcmp(sym + 6, name)) ||
83*4882a593Smuzhiyun 		(!strncmp(sym, ".ppc_", 5) && !strcmp(sym + 5, name + 4)) ||
84*4882a593Smuzhiyun 		(!strncmp(sym, ".ppc32_", 7) && !strcmp(sym + 7, name + 4)) ||
85*4882a593Smuzhiyun 		(!strncmp(sym, ".ppc64_", 7) && !strcmp(sym + 7, name + 4));
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun #else
arch_syscall_match_sym_name(const char * sym,const char * name)88*4882a593Smuzhiyun static inline bool arch_syscall_match_sym_name(const char *sym, const char *name)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun 	return !strcmp(sym, name) ||
91*4882a593Smuzhiyun 		(!strncmp(sym, "__se_sys", 8) && !strcmp(sym + 5, name)) ||
92*4882a593Smuzhiyun 		(!strncmp(sym, "ppc_", 4) && !strcmp(sym + 4, name + 4)) ||
93*4882a593Smuzhiyun 		(!strncmp(sym, "ppc32_", 6) && !strcmp(sym + 6, name + 4)) ||
94*4882a593Smuzhiyun 		(!strncmp(sym, "ppc64_", 6) && !strcmp(sym + 6, name + 4));
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun #endif /* PPC64_ELF_ABI_v1 */
97*4882a593Smuzhiyun #endif /* CONFIG_FTRACE_SYSCALLS */
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun #if defined(CONFIG_PPC64) && defined(CONFIG_FUNCTION_TRACER)
100*4882a593Smuzhiyun #include <asm/paca.h>
101*4882a593Smuzhiyun 
this_cpu_disable_ftrace(void)102*4882a593Smuzhiyun static inline void this_cpu_disable_ftrace(void)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun 	get_paca()->ftrace_enabled = 0;
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun 
this_cpu_enable_ftrace(void)107*4882a593Smuzhiyun static inline void this_cpu_enable_ftrace(void)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun 	get_paca()->ftrace_enabled = 1;
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun /* Disable ftrace on this CPU if possible (may not be implemented) */
this_cpu_set_ftrace_enabled(u8 ftrace_enabled)113*4882a593Smuzhiyun static inline void this_cpu_set_ftrace_enabled(u8 ftrace_enabled)
114*4882a593Smuzhiyun {
115*4882a593Smuzhiyun 	get_paca()->ftrace_enabled = ftrace_enabled;
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun 
this_cpu_get_ftrace_enabled(void)118*4882a593Smuzhiyun static inline u8 this_cpu_get_ftrace_enabled(void)
119*4882a593Smuzhiyun {
120*4882a593Smuzhiyun 	return get_paca()->ftrace_enabled;
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun void ftrace_free_init_tramp(void);
124*4882a593Smuzhiyun #else /* CONFIG_PPC64 */
this_cpu_disable_ftrace(void)125*4882a593Smuzhiyun static inline void this_cpu_disable_ftrace(void) { }
this_cpu_enable_ftrace(void)126*4882a593Smuzhiyun static inline void this_cpu_enable_ftrace(void) { }
this_cpu_set_ftrace_enabled(u8 ftrace_enabled)127*4882a593Smuzhiyun static inline void this_cpu_set_ftrace_enabled(u8 ftrace_enabled) { }
this_cpu_get_ftrace_enabled(void)128*4882a593Smuzhiyun static inline u8 this_cpu_get_ftrace_enabled(void) { return 1; }
ftrace_free_init_tramp(void)129*4882a593Smuzhiyun static inline void ftrace_free_init_tramp(void) { }
130*4882a593Smuzhiyun #endif /* CONFIG_PPC64 */
131*4882a593Smuzhiyun #endif /* !__ASSEMBLY__ */
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun #endif /* _ASM_POWERPC_FTRACE */
134