lkml.org 
[lkml]   [2022]   [Apr]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH -next] arm64: ftrace: Add DYNAMIC_FTRACE_WITH_ARGS support
Date
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(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 18a18a0e855d..a1b4c5800b38 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -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
diff --git a/arch/arm64/include/asm/ftrace.h b/arch/arm64/include/asm/ftrace.h
index 1494cfa8639b..2b4cd442c843 100644
--- a/arch/arm64/include/asm/ftrace.h
+++ b/arch/arm64/include/asm/ftrace.h
@@ -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);
diff --git a/arch/arm64/kernel/entry-ftrace.S b/arch/arm64/kernel/entry-ftrace.S
index e535480a4069..805287fedb01 100644
--- a/arch/arm64/kernel/entry-ftrace.S
+++ b/arch/arm64/kernel/entry-ftrace.S
@@ -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

--
2.17.1
\
 
 \ /
  Last update: 2022-04-20 04:12    [W:0.049 / U:0.336 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site