[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20220420020942.204224-1-lihuafei1@huawei.com>
Date: Wed, 20 Apr 2022 10:09:42 +0800
From: Li Huafei <lihuafei1@...wei.com>
To: <linux-kernel@...r.kernel.org>,
<linux-arm-kernel@...ts.infradead.org>
CC: <catalin.marinas@....com>, <will@...nel.org>,
<rostedt@...dmis.org>, <mingo@...hat.com>, <broonie@...nel.org>,
<mark.rutland@....com>, <ardb@...nel.org>, <lihuafei1@...wei.com>
Subject: [PATCH -next] arm64: ftrace: Add DYNAMIC_FTRACE_WITH_ARGS support
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@...wei.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
Powered by blists - more mailing lists