Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * arch/arm64/include/asm/ftrace.h
0004  *
0005  * Copyright (C) 2013 Linaro Limited
0006  * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
0007  */
0008 #ifndef __ASM_FTRACE_H
0009 #define __ASM_FTRACE_H
0010 
0011 #include <asm/insn.h>
0012 
0013 #define HAVE_FUNCTION_GRAPH_FP_TEST
0014 
0015 /*
0016  * HAVE_FUNCTION_GRAPH_RET_ADDR_PTR means that the architecture can provide a
0017  * "return address pointer" which can be used to uniquely identify a return
0018  * address which has been overwritten.
0019  *
0020  * On arm64 we use the address of the caller's frame record, which remains the
0021  * same for the lifetime of the instrumented function, unlike the return
0022  * address in the LR.
0023  */
0024 #define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
0025 
0026 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
0027 #define ARCH_SUPPORTS_FTRACE_OPS 1
0028 #else
0029 #define MCOUNT_ADDR     ((unsigned long)function_nocfi(_mcount))
0030 #endif
0031 
0032 /* The BL at the callsite's adjusted rec->ip */
0033 #define MCOUNT_INSN_SIZE    AARCH64_INSN_SIZE
0034 
0035 #define FTRACE_PLT_IDX      0
0036 #define FTRACE_REGS_PLT_IDX 1
0037 #define NR_FTRACE_PLTS      2
0038 
0039 /*
0040  * Currently, gcc tends to save the link register after the local variables
0041  * on the stack. This causes the max stack tracer to report the function
0042  * frame sizes for the wrong functions. By defining
0043  * ARCH_FTRACE_SHIFT_STACK_TRACER, it will tell the stack tracer to expect
0044  * to find the return address on the stack after the local variables have
0045  * been set up.
0046  *
0047  * Note, this may change in the future, and we will need to deal with that
0048  * if it were to happen.
0049  */
0050 #define ARCH_FTRACE_SHIFT_STACK_TRACER 1
0051 
0052 #ifndef __ASSEMBLY__
0053 #include <linux/compat.h>
0054 
0055 extern void _mcount(unsigned long);
0056 extern void *return_address(unsigned int);
0057 
0058 struct dyn_arch_ftrace {
0059     /* No extra data needed for arm64 */
0060 };
0061 
0062 extern unsigned long ftrace_graph_call;
0063 
0064 extern void return_to_handler(void);
0065 
0066 static inline unsigned long ftrace_call_adjust(unsigned long addr)
0067 {
0068     /*
0069      * Adjust addr to point at the BL in the callsite.
0070      * See ftrace_init_nop() for the callsite sequence.
0071      */
0072     if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS))
0073         return addr + AARCH64_INSN_SIZE;
0074     /*
0075      * addr is the address of the mcount call instruction.
0076      * recordmcount does the necessary offset calculation.
0077      */
0078     return addr;
0079 }
0080 
0081 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
0082 struct dyn_ftrace;
0083 struct ftrace_ops;
0084 struct ftrace_regs;
0085 
0086 int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
0087 #define ftrace_init_nop ftrace_init_nop
0088 
0089 void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
0090                struct ftrace_ops *op, struct ftrace_regs *fregs);
0091 #define ftrace_graph_func ftrace_graph_func
0092 #endif
0093 
0094 #define ftrace_return_address(n) return_address(n)
0095 
0096 /*
0097  * Because AArch32 mode does not share the same syscall table with AArch64,
0098  * tracing compat syscalls may result in reporting bogus syscalls or even
0099  * hang-up, so just do not trace them.
0100  * See kernel/trace/trace_syscalls.c
0101  *
0102  * x86 code says:
0103  * If the user really wants these, then they should use the
0104  * raw syscall tracepoints with filtering.
0105  */
0106 #define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS
0107 static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs)
0108 {
0109     return is_compat_task();
0110 }
0111 
0112 #define ARCH_HAS_SYSCALL_MATCH_SYM_NAME
0113 
0114 static inline bool arch_syscall_match_sym_name(const char *sym,
0115                            const char *name)
0116 {
0117     /*
0118      * Since all syscall functions have __arm64_ prefix, we must skip it.
0119      * However, as we described above, we decided to ignore compat
0120      * syscalls, so we don't care about __arm64_compat_ prefix here.
0121      */
0122     return !strcmp(sym + 8, name);
0123 }
0124 #endif /* ifndef __ASSEMBLY__ */
0125 
0126 #endif /* __ASM_FTRACE_H */