From: Andy Chiu <andybnac@gmail.com>
To: linux-riscv@lists.infradead.org, alexghiti@rivosinc.com,
palmer@dabbelt.com
Cc: "Andy Chiu" <andybnac@gmail.com>,
"Björn Töpel" <bjorn@rivosinc.com>,
linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
"Alexandre Ghiti" <alex@ghiti.fr>,
"Mark Rutland" <mark.rutland@arm.com>,
puranjay12@gmail.com, paul.walmsley@sifive.com,
greentime.hu@sifive.com, nick.hu@sifive.com,
nylon.chen@sifive.com, eric.lin@sifive.com,
vicent.chen@sifive.com, zong.li@sifive.com,
yongxuan.wang@sifive.com, samuel.holland@sifive.com,
olivia.chu@sifive.com, c2232430@gmail.com
Subject: [PATCH v4 11/12] riscv: ftrace: support direct call using call_ops
Date: Tue, 8 Apr 2025 02:08:35 +0800 [thread overview]
Message-ID: <20250407180838.42877-11-andybnac@gmail.com> (raw)
In-Reply-To: <20250407180838.42877-1-andybnac@gmail.com>
jump to FTRACE_ADDR if distance is out of reach
Co-developed-by: Björn Töpel <bjorn@rivosinc.com>
Signed-off-by: Björn Töpel <bjorn@rivosinc.com>
Signed-off-by: Andy Chiu <andybnac@gmail.com>
---
Changelog v4:
- New patch since v4
- Include Björn's fix for kprobe (adjusting ftrace address with
MCOUNT_INSN_SIZE)
- Clean out an unused variable
---
arch/riscv/Kconfig | 2 +-
arch/riscv/include/asm/ftrace.h | 6 ++++
arch/riscv/kernel/asm-offsets.c | 3 ++
arch/riscv/kernel/ftrace.c | 13 ++++-----
arch/riscv/kernel/mcount-dyn.S | 51 +++++++++++++++++++++------------
5 files changed, 48 insertions(+), 27 deletions(-)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index ec986c9120e3..8fdca6345fa3 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -152,7 +152,7 @@ config RISCV
select HAVE_DMA_CONTIGUOUS if MMU
select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && MMU && (CLANG_SUPPORTS_DYNAMIC_FTRACE || GCC_SUPPORTS_DYNAMIC_FTRACE)
select FUNCTION_ALIGNMENT_4B if HAVE_DYNAMIC_FTRACE && RISCV_ISA_C
- select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
+ select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS if HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS
select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS if (DYNAMIC_FTRACE_WITH_ARGS && !CFI_CLANG)
select HAVE_DYNAMIC_FTRACE_WITH_ARGS if HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_GRAPH_FUNC
diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h
index 6a5c0a7fb826..22ebea3c2b26 100644
--- a/arch/riscv/include/asm/ftrace.h
+++ b/arch/riscv/include/asm/ftrace.h
@@ -130,6 +130,9 @@ struct __arch_ftrace_regs {
unsigned long sp;
unsigned long s0;
unsigned long t1;
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
+ unsigned long direct_tramp;
+#endif
union {
unsigned long args[8];
struct {
@@ -223,10 +226,13 @@ void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
struct ftrace_ops *op, struct ftrace_regs *fregs);
#define ftrace_graph_func ftrace_graph_func
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
static inline void arch_ftrace_set_direct_caller(struct ftrace_regs *fregs, unsigned long addr)
{
arch_ftrace_regs(fregs)->t1 = addr;
}
+#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
+
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */
#endif /* __ASSEMBLY__ */
diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
index 2d96197a8abf..b26334075697 100644
--- a/arch/riscv/kernel/asm-offsets.c
+++ b/arch/riscv/kernel/asm-offsets.c
@@ -495,6 +495,9 @@ void asm_offsets(void)
OFFSET(STACKFRAME_RA, stackframe, ra);
#ifdef CONFIG_FUNCTION_TRACER
DEFINE(FTRACE_OPS_FUNC, offsetof(struct ftrace_ops, func));
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
+ DEFINE(FTRACE_OPS_DIRECT_CALL, offsetof(struct ftrace_ops, direct_call));
+#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
#endif
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS
diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c
index 30bcf60135d8..d65f06bfb457 100644
--- a/arch/riscv/kernel/ftrace.c
+++ b/arch/riscv/kernel/ftrace.c
@@ -16,7 +16,7 @@
unsigned long ftrace_call_adjust(unsigned long addr)
{
if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS))
- return addr + 8;
+ return addr + 8 + MCOUNT_AUIPC_SIZE;
return addr + MCOUNT_AUIPC_SIZE;
}
@@ -83,10 +83,9 @@ static const struct ftrace_ops *riscv64_rec_get_ops(struct dyn_ftrace *rec)
return ops;
}
-static int ftrace_rec_set_ops(const struct dyn_ftrace *rec,
- const struct ftrace_ops *ops)
+static int ftrace_rec_set_ops(const struct dyn_ftrace *rec, const struct ftrace_ops *ops)
{
- unsigned long literal = rec->ip - 8;
+ unsigned long literal = ALIGN_DOWN(rec->ip - 12, 8);
return patch_text_nosync((void *)literal, &ops, sizeof(ops));
}
@@ -117,7 +116,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
orig_addr = (unsigned long)&ftrace_caller;
distance = addr > orig_addr ? addr - orig_addr : orig_addr - addr;
if (distance > JALR_RANGE)
- return -EINVAL;
+ addr = FTRACE_ADDR;
return __ftrace_modify_call(pc, addr, false);
}
@@ -199,15 +198,13 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
unsigned long addr)
{
unsigned long caller = rec->ip - MCOUNT_AUIPC_SIZE;
- unsigned int call[2];
int ret;
- make_call_t0(caller, old_addr, call);
ret = ftrace_rec_update_ops(rec);
if (ret)
return ret;
- return __ftrace_modify_call(caller, addr, true);
+ return __ftrace_modify_call(caller, FTRACE_ADDR, true);
}
#endif
diff --git a/arch/riscv/kernel/mcount-dyn.S b/arch/riscv/kernel/mcount-dyn.S
index 699684eea7f0..48f6c4f7dca0 100644
--- a/arch/riscv/kernel/mcount-dyn.S
+++ b/arch/riscv/kernel/mcount-dyn.S
@@ -82,12 +82,9 @@
* +++++++++
**/
.macro SAVE_ABI_REGS
- mv t4, sp // Save original SP in T4
addi sp, sp, -FREGS_SIZE_ON_STACK
-
REG_S t0, FREGS_EPC(sp)
REG_S x1, FREGS_RA(sp)
- REG_S t4, FREGS_SP(sp) // Put original SP on stack
#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
REG_S x8, FREGS_S0(sp)
#endif
@@ -108,9 +105,12 @@
REG_S x15, FREGS_A5(sp)
REG_S x16, FREGS_A6(sp)
REG_S x17, FREGS_A7(sp)
+ mv a0, sp
+ addi a0, a0, FREGS_SIZE_ON_STACK
+ REG_S a0, FREGS_SP(sp) // Put original SP on stack
.endm
- .macro RESTORE_ABI_REGS, all=0
+ .macro RESTORE_ABI_REGS
REG_L t0, FREGS_EPC(sp)
REG_L x1, FREGS_RA(sp)
#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
@@ -139,6 +139,19 @@
.macro PREPARE_ARGS
addi a0, t0, -MCOUNT_JALR_SIZE // ip (callsite's jalr insn)
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS
+ mv a1, ra // parent_ip
+ REG_L a2, -16(t0) // op
+ REG_L ra, FTRACE_OPS_FUNC(a2) // op->func
+#else
+ la a1, function_trace_op
+ REG_L a2, 0(a1) // op
+ mv a1, ra // parent_ip
+#endif
+ mv a3, sp // regs
+ .endm
+
+SYM_FUNC_START(ftrace_caller)
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS
/*
* When CALL_OPS is enabled (2 or 4) nops [8B] are placed before the
@@ -158,19 +171,17 @@
* t0 is set to ip+8 after the jalr is executed at the callsite,
* so we find the associated op at t0-16.
*/
- mv a1, ra // parent_ip
- REG_L a2, -16(t0) // op
- REG_L ra, FTRACE_OPS_FUNC(a2) // op->func
-#else
- la a1, function_trace_op
- REG_L a2, 0(a1) // op
- mv a1, ra // parent_ip
-#endif
- mv a3, sp // regs
- .endm
+ REG_L t1, -16(t0) // op Should be SZ_REG instead of 16
-SYM_FUNC_START(ftrace_caller)
- mv t1, zero
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
+ /*
+ * If the op has a direct call, handle it immediately without
+ * saving/restoring registers.
+ */
+ REG_L t1, FTRACE_OPS_DIRECT_CALL(t1)
+ bnez t1, ftrace_caller_direct
+#endif
+#endif
SAVE_ABI_REGS
PREPARE_ARGS
@@ -182,10 +193,14 @@ SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL)
jalr ra, 0(ra)
#endif
RESTORE_ABI_REGS
- bnez t1, .Ldirect
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
+ bnez t1, ftrace_caller_direct
+#endif
jr t0
-.Ldirect:
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
+SYM_INNER_LABEL(ftrace_caller_direct, SYM_L_LOCAL)
jr t1
+#endif
SYM_FUNC_END(ftrace_caller)
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
--
2.39.3 (Apple Git-145)
next prev parent reply other threads:[~2025-04-07 18:09 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-07 18:08 [PATCH v4 01/12] riscv: ftrace: support fastcc in Clang for WITH_ARGS Andy Chiu
2025-04-07 18:08 ` [PATCH v4 02/12] riscv: ftrace factor out code defined by !WITH_ARG Andy Chiu
2025-04-07 18:08 ` [PATCH v4 03/12] riscv: ftrace: align patchable functions to 4 Byte boundary Andy Chiu
2025-04-07 18:08 ` [PATCH v4 04/12] kernel: ftrace: export ftrace_sync_ipi Andy Chiu
2025-04-08 22:31 ` kernel test robot
2025-04-23 8:13 ` Alexandre Ghiti
2025-04-07 18:08 ` [PATCH v4 05/12] riscv: ftrace: prepare ftrace for atomic code patching Andy Chiu
2025-04-11 13:15 ` Robbin Ehn
2025-04-23 8:22 ` Alexandre Ghiti
2025-05-05 14:06 ` Alexandre Ghiti
2025-05-07 14:18 ` Andy Chiu
2025-05-07 14:35 ` Alexandre Ghiti
2025-04-07 18:08 ` [PATCH v4 06/12] riscv: ftrace: do not use stop_machine to update code Andy Chiu
2025-04-07 18:08 ` [PATCH v4 07/12] riscv: vector: Support calling schedule() for preemptible Vector Andy Chiu
2025-04-07 18:08 ` [PATCH v4 08/12] riscv: add a data fence for CMODX in the kernel mode Andy Chiu
2025-04-07 18:08 ` [PATCH v4 09/12] riscv: ftrace: support PREEMPT Andy Chiu
2025-04-07 18:08 ` [PATCH v4 10/12] riscv: Implement HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS Andy Chiu
2026-02-21 12:15 ` Conor Dooley
2026-02-23 15:18 ` Puranjay Mohan
2026-02-23 15:27 ` Conor Dooley
2026-02-23 15:41 ` Puranjay Mohan
2026-02-23 16:29 ` Conor Dooley
2026-02-23 17:36 ` Puranjay Mohan
2026-02-23 17:41 ` Conor Dooley
2025-04-07 18:08 ` Andy Chiu [this message]
2025-04-07 18:08 ` [PATCH v4 12/12] riscv: Documentation: add a description about dynamic ftrace Andy Chiu
2025-04-11 12:02 ` Robbin Ehn
2025-04-10 20:05 ` [PATCH v4 01/12] riscv: ftrace: support fastcc in Clang for WITH_ARGS Björn Töpel
2025-05-07 13:58 ` Andy Chiu
2025-06-02 22:12 ` patchwork-bot+linux-riscv
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250407180838.42877-11-andybnac@gmail.com \
--to=andybnac@gmail.com \
--cc=alex@ghiti.fr \
--cc=alexghiti@rivosinc.com \
--cc=bjorn@rivosinc.com \
--cc=c2232430@gmail.com \
--cc=eric.lin@sifive.com \
--cc=greentime.hu@sifive.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=nick.hu@sifive.com \
--cc=nylon.chen@sifive.com \
--cc=olivia.chu@sifive.com \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=puranjay12@gmail.com \
--cc=samuel.holland@sifive.com \
--cc=vicent.chen@sifive.com \
--cc=yongxuan.wang@sifive.com \
--cc=zong.li@sifive.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox