@@ -177,6 +177,8 @@ config ARM64
select HAVE_DEBUG_KMEMLEAK
select HAVE_DMA_CONTIGUOUS
select HAVE_DYNAMIC_FTRACE
+ select HAVE_DYNAMIC_FTRACE_WITH_ARGS \
+ if HAVE_DYNAMIC_FTRACE_WITH_REGS
select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY \
if DYNAMIC_FTRACE_WITH_REGS
select HAVE_EFFICIENT_UNALIGNED_ACCESS
@@ -78,6 +78,23 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
return addr;
}
+#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS
+struct ftrace_regs {
+ struct pt_regs regs;
+};
+
+static __always_inline struct pt_regs *
+arch_ftrace_get_regs(struct ftrace_regs *fregs)
+{
+ struct pt_regs *regs = &fregs->regs;
+
+ /* When FL_SAVE_REGS is not set, X10 is set to zero */
+ if (!pt_regs_read_reg(regs, 10))
+ return NULL;
+ return regs;
+}
+#endif /* CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS */
+
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
struct dyn_ftrace;
int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
@@ -46,6 +46,8 @@
/* Optionally save the callee-saved registers, always save the FP */
.if \allregs == 1
+ /* Set X10 to 1 (just non-zero) for ops with FL_SAVE_REGS flag set */
+ mov x10, #1
stp x10, x11, [sp, #S_X10]
stp x12, x13, [sp, #S_X12]
stp x14, x15, [sp, #S_X14]
@@ -57,6 +59,9 @@
stp x26, x27, [sp, #S_X26]
stp x28, x29, [sp, #S_X28]
.else
+ /* Set X10 to 0 for ops without FL_SAVE_REGS flag */
+ mov x10, #0
+ str x10, [sp, #S_X10]
str x29, [sp, #S_FP]
.endif
DYNAMIC_FTRACE_WITH_ARGS allows ftrace_ops without the FL_SAVE_REGS flag set (via the "ftrace_caller" trampoline) to fetch all parameters and stack pointer. On arm64, under the DYNAMIC_FTRACE_WITH_REGS implementation, ftrace_caller() already supports filling the above registers into pt_regs, all that remains to be done is to ensure that arch_ftrace_get_regs() returns NULL when FL_SAVE_REGS is not set. We use pt_regs::regs[10] to identify whether the FL_SAVE_REGS flag is set. The mcount-based implementation supports DYNAMIC_FTRACE_WITH_ARGS with some difficulty, as some registers (e.g. X0) are already clobbered before entering the trampoline. We need to rely on gcc's "-fpatchable-function-entry" feature, so here we have DYNAMIC_FTRACE_WITH_ARGS depending on DYNAMIC_FTRACE_WITH_REGS, and the mcount-based implementation is unaffected. Signed-off-by: Li Huafei <lihuafei1@huawei.com> --- arch/arm64/Kconfig | 2 ++ arch/arm64/include/asm/ftrace.h | 17 +++++++++++++++++ arch/arm64/kernel/entry-ftrace.S | 5 +++++ 3 files changed, 24 insertions(+)