* [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
` (2 more replies)
0 siblings, 3 replies; 8+ 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] 8+ 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-09 7:19 ` Charlie Jenkins 2026-07-01 8:10 ` [PATCH v6 2/2] riscv: kprobes: add test case for c.jal instruction simulation Xiaofeng Yuan 2026-07-10 18:35 ` [PATCH v6 0/2] riscv: add c.jal instruction simulation for kprobes Paul Walmsley 2 siblings, 2 replies; 8+ 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] 8+ 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 2026-07-09 7:19 ` Charlie Jenkins 1 sibling, 0 replies; 8+ 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] 8+ 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 @ 2026-07-09 7:19 ` Charlie Jenkins 2026-07-10 18:39 ` Paul Walmsley 1 sibling, 1 reply; 8+ messages in thread From: Charlie Jenkins @ 2026-07-09 7:19 UTC (permalink / raw) To: Xiaofeng Yuan Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Charlie Jenkins, Nam Cao, linux-riscv, linux-kernel # Add your code comments below. There is no need to trim or delete # any existing content -- just insert your comments under the relevant # lines of code. Lines starting with "> " are quoted diff context and # lines starting with "| " are comments from other reviewers. # The final email will be reformatted automatically to include only # the sections that have your comments. # > 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> > > diff --git a/arch/riscv/kernel/probes/decode-insn.c b/arch/riscv/kernel/probes/decode-insn.c > index 65d9590bfb9f..433d9035b888 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 fa581590c1f8..f8a2f6857877 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 44ebbc444db9..b89e1bb01842 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); Reviewed-by: Charlie Jenkins <thecharlesjenkins@gmail.com> Tested-by: Charlie Jenkins <thecharlesjenkins@gmail.com> -- - Charlie ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v6 1/2] riscv: probes: simulate c.jal instruction 2026-07-09 7:19 ` Charlie Jenkins @ 2026-07-10 18:39 ` Paul Walmsley 0 siblings, 0 replies; 8+ messages in thread From: Paul Walmsley @ 2026-07-10 18:39 UTC (permalink / raw) To: Charlie Jenkins, Nam Cao Cc: Xiaofeng Yuan, Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-riscv, linux-kernel Hi Nam, Charlie, On Thu, 9 Jul 2026, Charlie Jenkins wrote: > Reviewed-by: Charlie Jenkins <thecharlesjenkins@gmail.com> > Tested-by: Charlie Jenkins <thecharlesjenkins@gmail.com> Thank you both for posting Reviewed-by:s and Tested-by:s for these patches. One request: at the end of your Tested-by:s, it's very helpful for myself and others if we know what platform they were tested on, and whether the testing was simply boot testing, or whether the tests were direct functional tests of the code being patched. So for example, something along the lines of the following would be really great: Tested-by: J. Kernel Developer <email@address> # QEMU; kprobes or Tested-by: J. Kernel Developer <email@address> # Litex VexRISCV; boot Thanks again for reviewing and testing! - Paul ^ permalink raw reply [flat|nested] 8+ 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 2026-07-09 7:19 ` Charlie Jenkins 2026-07-10 18:35 ` [PATCH v6 0/2] riscv: add c.jal instruction simulation for kprobes Paul Walmsley 2 siblings, 1 reply; 8+ 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] 8+ messages in thread
* Re: [PATCH v6 2/2] riscv: kprobes: add test case for c.jal instruction simulation 2026-07-01 8:10 ` [PATCH v6 2/2] riscv: kprobes: add test case for c.jal instruction simulation Xiaofeng Yuan @ 2026-07-09 7:19 ` Charlie Jenkins 0 siblings, 0 replies; 8+ messages in thread From: Charlie Jenkins @ 2026-07-09 7:19 UTC (permalink / raw) To: Xiaofeng Yuan Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Charlie Jenkins, Nam Cao, linux-riscv, linux-kernel # Add your code comments below. There is no need to trim or delete # any existing content -- just insert your comments under the relevant # lines of code. Lines starting with "> " are quoted diff context and # lines starting with "| " are comments from other reviewers. # The final email will be reformatted automatically to include only # the sections that have your comments. # > 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> > > diff --git a/arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S b/arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S > index f16deee9e091..15e50934bbd7 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) Reviewed-by: Charlie Jenkins <thecharlesjenkins@gmail.com> Tested-by: Charlie Jenkins <thecharlesjenkins@gmail.com> -- - Charlie ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v6 0/2] riscv: add c.jal instruction simulation for kprobes 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 ` [PATCH v6 2/2] riscv: kprobes: add test case for c.jal instruction simulation Xiaofeng Yuan @ 2026-07-10 18:35 ` Paul Walmsley 2 siblings, 0 replies; 8+ messages in thread From: Paul Walmsley @ 2026-07-10 18:35 UTC (permalink / raw) To: Xiaofeng Yuan Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Charlie Jenkins, Nam Cao, linux-riscv, linux-kernel On Wed, 1 Jul 2026, Xiaofeng Yuan wrote: > 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. Thanks, queued for v7.3. - Paul ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-07-10 18:39 UTC | newest] Thread overview: 8+ 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-09 7:19 ` Charlie Jenkins 2026-07-10 18:39 ` Paul Walmsley 2026-07-01 8:10 ` [PATCH v6 2/2] riscv: kprobes: add test case for c.jal instruction simulation Xiaofeng Yuan 2026-07-09 7:19 ` Charlie Jenkins 2026-07-10 18:35 ` [PATCH v6 0/2] riscv: add c.jal instruction simulation for kprobes Paul Walmsley
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox