The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH v6 0/2] riscv: add c.jal instruction simulation for kprobes
@ 2026-07-01  8:10 Xiaofeng Yuan
  2026-07-01  8:10 ` [PATCH v6 1/2] riscv: probes: simulate c.jal instruction Xiaofeng Yuan
  2026-07-01  8:10 ` [PATCH v6 2/2] riscv: kprobes: add test case for c.jal instruction simulation Xiaofeng Yuan
  0 siblings, 2 replies; 4+ messages in thread
From: Xiaofeng Yuan @ 2026-07-01  8:10 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou
  Cc: Charlie Jenkins, Nam Cao, linux-riscv, linux-kernel, xiaofengmian

The c.jal instruction is part of the RISC-V compressed instruction set
and is defined only on RV32.  Currently kprobes rejects it, causing
probes placed on c.jal to fail.

This series adds simulation support for c.jal and includes a test
case by Nam Cao.

Changes since v5:
  - Removed the #if __riscv_xlen == 32 guards around simulate_c_jal()
    as both Charlie Jenkins and Nam Cao agreed they are unnecessary.
    On RV64, riscv_insn_is_c_jal() always returns 0 so the simulation
    code is never invoked, and the small overhead in kernel size is
    acceptable.
  - Included Nam Cao's test case for c.jal instruction simulation.

Changes since v4:
  - Reuse simulate_c_j() for the jump logic (Nam Cao)
  - Use direct register assignment instead of rv_insn_reg_set_val()
  - Move RISCV_INSN_SET_SIMULATE(c_jal) to group with other compressed
    jump instructions

Nam Cao (1):
  riscv: kprobes: add test case for c.jal instruction simulation

Xiaofeng Yuan (1):
  riscv: probes: simulate c.jal instruction

Nam Cao (1):
  riscv: kprobes: add test case for c.jal instruction simulation

Xiaofeng Yuan (1):
  riscv: probes: simulate c.jal instruction

 arch/riscv/kernel/probes/decode-insn.c        |  2 +-
 arch/riscv/kernel/probes/simulate-insn.c      |  7 ++++++
 arch/riscv/kernel/probes/simulate-insn.h      |  1 +
 .../kernel/tests/kprobes/test-kprobes-asm.S   | 24 +++++++++++++++++++
 4 files changed, 33 insertions(+), 1 deletion(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v6 1/2] riscv: probes: simulate c.jal instruction
  2026-07-01  8:10 [PATCH v6 0/2] riscv: add c.jal instruction simulation for kprobes Xiaofeng Yuan
@ 2026-07-01  8:10 ` Xiaofeng Yuan
  2026-07-02  9:49   ` Nam Cao
  2026-07-01  8:10 ` [PATCH v6 2/2] riscv: kprobes: add test case for c.jal instruction simulation Xiaofeng Yuan
  1 sibling, 1 reply; 4+ messages in thread
From: Xiaofeng Yuan @ 2026-07-01  8:10 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou
  Cc: Charlie Jenkins, Nam Cao, linux-riscv, linux-kernel, xiaofengmian

The c.jal instruction is currently marked REJECTED in kprobes
instruction decoding, but it should be SIMULATED like other
compressed jump instructions.

Add simulate_c_jal() which saves the return address to RA and
sets the program counter to the target offset, reusing
simulate_c_j for the common jump logic.

Although c.jal is RV32-only, the function compiles unconditionally.
On RV64, riscv_insn_is_c_jal() always returns 0, so the simulation
code is never invoked and the small overhead in kernel size is
acceptable.

Signed-off-by: Xiaofeng Yuan <xiaofengmian@163.com>
---
 arch/riscv/kernel/probes/decode-insn.c   | 2 +-
 arch/riscv/kernel/probes/simulate-insn.c | 7 +++++++
 arch/riscv/kernel/probes/simulate-insn.h | 1 +
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/kernel/probes/decode-insn.c b/arch/riscv/kernel/probes/decode-insn.c
index 65d9590bf..433d9035b 100644
--- a/arch/riscv/kernel/probes/decode-insn.c
+++ b/arch/riscv/kernel/probes/decode-insn.c
@@ -29,12 +29,12 @@ riscv_probe_decode_insn(probe_opcode_t *addr, struct arch_probe_insn *api)
 	 * TODO: the REJECTED ones below need to be implemented
 	 */
 #ifdef CONFIG_RISCV_ISA_C
-	RISCV_INSN_REJECTED(c_jal,		insn);
 	RISCV_INSN_REJECTED(c_ebreak,		insn);
 
 	RISCV_INSN_SET_SIMULATE(c_j,		insn);
 	RISCV_INSN_SET_SIMULATE(c_jr,		insn);
 	RISCV_INSN_SET_SIMULATE(c_jalr,		insn);
+	RISCV_INSN_SET_SIMULATE(c_jal,		insn);
 	RISCV_INSN_SET_SIMULATE(c_beqz,		insn);
 	RISCV_INSN_SET_SIMULATE(c_bnez,		insn);
 #endif
diff --git a/arch/riscv/kernel/probes/simulate-insn.c b/arch/riscv/kernel/probes/simulate-insn.c
index fa581590c..f8a2f6857 100644
--- a/arch/riscv/kernel/probes/simulate-insn.c
+++ b/arch/riscv/kernel/probes/simulate-insn.c
@@ -163,6 +163,13 @@ bool __kprobes simulate_c_j(u32 opcode, unsigned long addr, struct pt_regs *regs
 	return true;
 }
 
+bool __kprobes simulate_c_jal(u32 opcode, unsigned long addr, struct pt_regs *regs)
+{
+	regs->ra = addr + 2;
+
+	return simulate_c_j(opcode, addr, regs);
+}
+
 static bool __kprobes simulate_c_jr_jalr(u32 opcode, unsigned long addr, struct pt_regs *regs,
 					 bool is_jalr)
 {
diff --git a/arch/riscv/kernel/probes/simulate-insn.h b/arch/riscv/kernel/probes/simulate-insn.h
index 44ebbc444..b89e1bb01 100644
--- a/arch/riscv/kernel/probes/simulate-insn.h
+++ b/arch/riscv/kernel/probes/simulate-insn.h
@@ -25,6 +25,7 @@ bool simulate_branch(u32 opcode, unsigned long addr, struct pt_regs *regs);
 bool simulate_jal(u32 opcode, unsigned long addr, struct pt_regs *regs);
 bool simulate_jalr(u32 opcode, unsigned long addr, struct pt_regs *regs);
 bool simulate_c_j(u32 opcode, unsigned long addr, struct pt_regs *regs);
+bool simulate_c_jal(u32 opcode, unsigned long addr, struct pt_regs *regs);
 bool simulate_c_jr(u32 opcode, unsigned long addr, struct pt_regs *regs);
 bool simulate_c_jalr(u32 opcode, unsigned long addr, struct pt_regs *regs);
 bool simulate_c_bnez(u32 opcode, unsigned long addr, struct pt_regs *regs);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v6 2/2] riscv: kprobes: add test case for c.jal instruction simulation
  2026-07-01  8:10 [PATCH v6 0/2] riscv: add c.jal instruction simulation for kprobes Xiaofeng Yuan
  2026-07-01  8:10 ` [PATCH v6 1/2] riscv: probes: simulate c.jal instruction Xiaofeng Yuan
@ 2026-07-01  8:10 ` Xiaofeng Yuan
  1 sibling, 0 replies; 4+ messages in thread
From: Xiaofeng Yuan @ 2026-07-01  8:10 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou
  Cc: Charlie Jenkins, Nam Cao, linux-riscv, linux-kernel, xiaofengmian

From: Nam Cao <namcao@linutronix.de>

Add a test case validating that kprobes correctly simulates the
c.jal instruction on RV32.

The test uses two probe points: a forward c.jal and a backward
c.jal, and verifies that the containing function returns the
expected magic value KPROBE_TEST_MAGIC after kprobe interception.

Co-developed-by: Xiaofeng Yuan <xiaofengmian@163.com>
Signed-off-by: Nam Cao <namcao@linutronix.de>
Signed-off-by: Xiaofeng Yuan <xiaofengmian@163.com>
---
 .../kernel/tests/kprobes/test-kprobes-asm.S   | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S b/arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S
index f16deee9e..15e50934b 100644
--- a/arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S
+++ b/arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S
@@ -179,6 +179,23 @@ test_kprobes_c_bnez_addr3:
 	ret
 SYM_FUNC_END(test_kprobes_c_bnez)
 
+#ifdef CONFIG_32BIT
+SYM_FUNC_START(test_kprobes_c_jal)
+	li a0, 0
+	mv a1, ra
+test_kprobes_c_jal_addr1:
+	c.jal 2f
+	ret
+1:	li a0, KPROBE_TEST_MAGIC_UPPER
+	ret
+test_kprobes_c_jal_addr2:
+2:	c.jal 1b
+	li a2, KPROBE_TEST_MAGIC_LOWER
+	add a0, a0, a2
+	jr a1
+SYM_FUNC_END(test_kprobes_c_jal)
+#endif
+
 #endif /* CONFIG_RISCV_ISA_C */
 
 .section .rodata
@@ -209,6 +226,10 @@ SYM_DATA_START(test_kprobes_addresses)
 	RISCV_PTR test_kprobes_c_bnez_addr1
 	RISCV_PTR test_kprobes_c_bnez_addr2
 	RISCV_PTR test_kprobes_c_bnez_addr3
+#ifdef CONFIG_32BIT
+	RISCV_PTR test_kprobes_c_jal_addr1
+	RISCV_PTR test_kprobes_c_jal_addr2
+#endif
 #endif /* CONFIG_RISCV_ISA_C */
 	RISCV_PTR 0
 SYM_DATA_END(test_kprobes_addresses)
@@ -226,6 +247,9 @@ SYM_DATA_START(test_kprobes_functions)
 	RISCV_PTR test_kprobes_c_jalr
 	RISCV_PTR test_kprobes_c_beqz
 	RISCV_PTR test_kprobes_c_bnez
+#ifdef CONFIG_32BIT
+	RISCV_PTR test_kprobes_c_jal
+#endif
 #endif /* CONFIG_RISCV_ISA_C */
 	RISCV_PTR 0
 SYM_DATA_END(test_kprobes_functions)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v6 1/2] riscv: probes: simulate c.jal instruction
  2026-07-01  8:10 ` [PATCH v6 1/2] riscv: probes: simulate c.jal instruction Xiaofeng Yuan
@ 2026-07-02  9:49   ` Nam Cao
  0 siblings, 0 replies; 4+ messages in thread
From: Nam Cao @ 2026-07-02  9:49 UTC (permalink / raw)
  To: Xiaofeng Yuan, Paul Walmsley, Palmer Dabbelt, Albert Ou
  Cc: Charlie Jenkins, linux-riscv, linux-kernel, xiaofengmian

Xiaofeng Yuan <xiaofengmian@163.com> writes:

> The c.jal instruction is currently marked REJECTED in kprobes
> instruction decoding, but it should be SIMULATED like other
> compressed jump instructions.
>
> Add simulate_c_jal() which saves the return address to RA and
> sets the program counter to the target offset, reusing
> simulate_c_j for the common jump logic.
>
> Although c.jal is RV32-only, the function compiles unconditionally.
> On RV64, riscv_insn_is_c_jal() always returns 0, so the simulation
> code is never invoked and the small overhead in kernel size is
> acceptable.
>
> Signed-off-by: Xiaofeng Yuan <xiaofengmian@163.com>

Reviewed-by: Nam Cao <namcao@linutronix.de>
Tested-by: Nam Cao <namcao@linutronix.de>

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-07-02  9:49 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-01  8:10 [PATCH v6 0/2] riscv: add c.jal instruction simulation for kprobes Xiaofeng Yuan
2026-07-01  8:10 ` [PATCH v6 1/2] riscv: probes: simulate c.jal instruction Xiaofeng Yuan
2026-07-02  9:49   ` Nam Cao
2026-07-01  8:10 ` [PATCH v6 2/2] riscv: kprobes: add test case for c.jal instruction simulation Xiaofeng Yuan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox