* [PATCH 0/2] riscv: kprobes: simulate nop and c.nop instructions @ 2026-08-19 10:14 Xiaofeng Yuan 2026-08-19 10:14 ` [PATCH 1/2] " Xiaofeng Yuan 2026-08-19 10:14 ` [PATCH 2/2] riscv: kprobes: add nop and c.nop to the KUnit test Xiaofeng Yuan 0 siblings, 2 replies; 6+ messages in thread From: Xiaofeng Yuan @ 2026-08-19 10:14 UTC (permalink / raw) To: Paul Walmsley, Palmer Dabbelt Cc: Albert Ou, Nam Cao, linux-riscv, yuanxiaofeng nop and c.nop have no architectural effect, so handling them through an out-of-line instruction slot and single-stepping is pure overhead. This series simulates them directly in the breakpoint handler by advancing the program counter, following the approach already used on arm64, and extends the RISC-V kprobes KUnit test to cover both paths. Patch 1 adds the simulation. Patch 2 extends the KUnit test with test_kprobes_nop and test_kprobes_c_nop. Verified by cross-compiling for RISC-V and running the kprobes KUnit test in QEMU (ok 1 kprobes_riscv). Xiaofeng Yuan (2): riscv: kprobes: simulate nop and c.nop instructions riscv: kprobes: add nop and c.nop to the KUnit test arch/riscv/include/asm/insn.h | 11 ++++++++ arch/riscv/kernel/probes/decode-insn.c | 6 +++++ arch/riscv/kernel/probes/simulate-insn.c | 14 ++++++++++ arch/riscv/kernel/probes/simulate-insn.h | 2 ++ .../kernel/tests/kprobes/test-kprobes-asm.S | 27 +++++++++++++++++++ 5 files changed, 60 insertions(+) -- 2.43.0 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] riscv: kprobes: simulate nop and c.nop instructions 2026-08-19 10:14 [PATCH 0/2] riscv: kprobes: simulate nop and c.nop instructions Xiaofeng Yuan @ 2026-08-19 10:14 ` Xiaofeng Yuan 2026-08-19 11:54 ` Nam Cao 2026-08-19 10:14 ` [PATCH 2/2] riscv: kprobes: add nop and c.nop to the KUnit test Xiaofeng Yuan 1 sibling, 1 reply; 6+ messages in thread From: Xiaofeng Yuan @ 2026-08-19 10:14 UTC (permalink / raw) To: Paul Walmsley, Palmer Dabbelt Cc: Albert Ou, Nam Cao, linux-riscv, yuanxiaofeng nop and c.nop have no architectural effect, so allocating an out-of-line instruction slot and single-stepping through them is pure overhead. Simulate them directly in the breakpoint handler by advancing the program counter, following the approach already used on arm64. This avoids slot allocation, text patching, IRQ flag save/restore and the single-step exception for these instructions. Compile tested on RISC-V, and verified with the RISC-V kprobes KUnit test which now covers nop and c.nop. Signed-off-by: Xiaofeng Yuan <yuanxiaofeng@eswincomputing.com> --- arch/riscv/include/asm/insn.h | 11 +++++++++++ arch/riscv/kernel/probes/decode-insn.c | 6 ++++++ arch/riscv/kernel/probes/simulate-insn.c | 14 ++++++++++++++ arch/riscv/kernel/probes/simulate-insn.h | 2 ++ 4 files changed, 33 insertions(+) diff --git a/arch/riscv/include/asm/insn.h b/arch/riscv/include/asm/insn.h index c3005573e8..5b3944a5fa 100644 --- a/arch/riscv/include/asm/insn.h +++ b/arch/riscv/include/asm/insn.h @@ -228,6 +228,15 @@ #define RVG_MASK_EBREAK 0xffffffff #define RVG_MASK_SRET 0xffffffff +/* + * NOP and C.NOP have no variable fields, so all bits must match. + * NOP is encoded as ADDI x0, x0, 0 (0x00000013), C.NOP as C.ADDI x0, 0 (0x0001). + */ +#define RVG_MATCH_NOP 0x00000013 +#define RVG_MASK_NOP 0xffffffff +#define RVC_MATCH_C_NOP 0x0001 +#define RVC_MASK_C_NOP 0xffff + #define __INSN_LENGTH_MASK _UL(0x3) #define __INSN_LENGTH_GE_32 _UL(0x3) #define __INSN_OPCODE_MASK _UL(0x7F) @@ -262,6 +271,8 @@ __RISCV_INSN_FUNCS(c_ebreak, RVC_MASK_C_EBREAK, RVC_MATCH_C_EBREAK) __RISCV_INSN_FUNCS(ebreak, RVG_MASK_EBREAK, RVG_MATCH_EBREAK) __RISCV_INSN_FUNCS(sret, RVG_MASK_SRET, RVG_MATCH_SRET) __RISCV_INSN_FUNCS(fence, RVG_MASK_FENCE, RVG_MATCH_FENCE); +__RISCV_INSN_FUNCS(nop, RVG_MASK_NOP, RVG_MATCH_NOP) +__RISCV_INSN_FUNCS(c_nop, RVC_MASK_C_NOP, RVC_MATCH_C_NOP) /* special case to catch _any_ system instruction */ static __always_inline bool riscv_insn_is_system(u32 code) diff --git a/arch/riscv/kernel/probes/decode-insn.c b/arch/riscv/kernel/probes/decode-insn.c index 65d9590bfb..d28408f0b7 100644 --- a/arch/riscv/kernel/probes/decode-insn.c +++ b/arch/riscv/kernel/probes/decode-insn.c @@ -44,5 +44,11 @@ riscv_probe_decode_insn(probe_opcode_t *addr, struct arch_probe_insn *api) RISCV_INSN_SET_SIMULATE(auipc, insn); RISCV_INSN_SET_SIMULATE(branch, insn); + /* Simulate NOP for better performance */ + RISCV_INSN_SET_SIMULATE(nop, insn); +#ifdef CONFIG_RISCV_ISA_C + RISCV_INSN_SET_SIMULATE(c_nop, insn); +#endif + return INSN_GOOD; } diff --git a/arch/riscv/kernel/probes/simulate-insn.c b/arch/riscv/kernel/probes/simulate-insn.c index fa581590c1..3b22d3ad53 100644 --- a/arch/riscv/kernel/probes/simulate-insn.c +++ b/arch/riscv/kernel/probes/simulate-insn.c @@ -237,3 +237,17 @@ bool __kprobes simulate_c_beqz(u32 opcode, unsigned long addr, struct pt_regs *r { return simulate_c_bnez_beqz(opcode, addr, regs, false); } + +bool __kprobes simulate_nop(u32 opcode, unsigned long addr, struct pt_regs *regs) +{ + instruction_pointer_set(regs, addr + 4); + + return true; +} + +bool __kprobes simulate_c_nop(u32 opcode, unsigned long addr, struct pt_regs *regs) +{ + instruction_pointer_set(regs, addr + 2); + + return true; +} diff --git a/arch/riscv/kernel/probes/simulate-insn.h b/arch/riscv/kernel/probes/simulate-insn.h index 44ebbc444d..7e0936613f 100644 --- a/arch/riscv/kernel/probes/simulate-insn.h +++ b/arch/riscv/kernel/probes/simulate-insn.h @@ -29,5 +29,7 @@ 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); bool simulate_c_beqz(u32 opcode, unsigned long addr, struct pt_regs *regs); +bool simulate_nop(u32 opcode, unsigned long addr, struct pt_regs *regs); +bool simulate_c_nop(u32 opcode, unsigned long addr, struct pt_regs *regs); #endif /* _RISCV_KERNEL_PROBES_SIMULATE_INSN_H */ -- 2.43.0 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] riscv: kprobes: simulate nop and c.nop instructions 2026-08-19 10:14 ` [PATCH 1/2] " Xiaofeng Yuan @ 2026-08-19 11:54 ` Nam Cao 0 siblings, 0 replies; 6+ messages in thread From: Nam Cao @ 2026-08-19 11:54 UTC (permalink / raw) To: Xiaofeng Yuan, Paul Walmsley, Palmer Dabbelt Cc: Albert Ou, Nam Cao, linux-riscv, yuanxiaofeng Xiaofeng Yuan <yuanxiaofeng@eswincomputing.com> writes: > nop and c.nop have no architectural effect, so allocating an > out-of-line instruction slot and single-stepping through them is > pure overhead. Simulate them directly in the breakpoint handler > by advancing the program counter, following the approach already > used on arm64. > > This avoids slot allocation, text patching, IRQ flag save/restore > and the single-step exception for these instructions. > > Compile tested on RISC-V, and verified with the RISC-V kprobes > KUnit test which now covers nop and c.nop. For RISC-V, how common is installing probes on nop instructions? Looking at the commit adding nop simulation on Arm, I see it is useful for probes on USDT. Is this also the case for RISC-V? Additionally, it would be great if there is a benchmark to justify adding this. Nam _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2] riscv: kprobes: add nop and c.nop to the KUnit test 2026-08-19 10:14 [PATCH 0/2] riscv: kprobes: simulate nop and c.nop instructions Xiaofeng Yuan 2026-08-19 10:14 ` [PATCH 1/2] " Xiaofeng Yuan @ 2026-08-19 10:14 ` Xiaofeng Yuan 2026-08-19 11:58 ` Nam Cao 1 sibling, 1 reply; 6+ messages in thread From: Xiaofeng Yuan @ 2026-08-19 10:14 UTC (permalink / raw) To: Paul Walmsley, Palmer Dabbelt Cc: Albert Ou, Nam Cao, linux-riscv, yuanxiaofeng Extend the RISC-V kprobes KUnit test with test_kprobes_nop and test_kprobes_c_nop, covering both the 32-bit nop and the compressed c.nop simulation paths. Signed-off-by: Xiaofeng Yuan <yuanxiaofeng@eswincomputing.com> --- .../kernel/tests/kprobes/test-kprobes-asm.S | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S b/arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S index f16deee9e0..8d8f460cb6 100644 --- a/arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S +++ b/arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S @@ -181,6 +181,29 @@ SYM_FUNC_END(test_kprobes_c_bnez) #endif /* CONFIG_RISCV_ISA_C */ +SYM_FUNC_START(test_kprobes_nop) + .option push + .option norvc +test_kprobes_nop_addr: + nop + .option pop + li a0, KPROBE_TEST_MAGIC_LOWER + li a1, KPROBE_TEST_MAGIC_UPPER + add a0, a0, a1 + ret +SYM_FUNC_END(test_kprobes_nop) + +#ifdef CONFIG_RISCV_ISA_C +SYM_FUNC_START(test_kprobes_c_nop) +test_kprobes_c_nop_addr: + c.nop + li a0, KPROBE_TEST_MAGIC_LOWER + li a1, KPROBE_TEST_MAGIC_UPPER + add a0, a0, a1 + ret +SYM_FUNC_END(test_kprobes_c_nop) +#endif /* CONFIG_RISCV_ISA_C */ + .section .rodata SYM_DATA_START(test_kprobes_addresses) RISCV_PTR test_kprobes_add_addr1 @@ -197,7 +220,9 @@ SYM_DATA_START(test_kprobes_addresses) RISCV_PTR test_kprobes_branch_addr6 RISCV_PTR test_kprobes_branch_addr7 RISCV_PTR test_kprobes_branch_addr8 + RISCV_PTR test_kprobes_nop_addr #ifdef CONFIG_RISCV_ISA_C + RISCV_PTR test_kprobes_c_nop_addr RISCV_PTR test_kprobes_branch_c_j_addr1 RISCV_PTR test_kprobes_branch_c_j_addr2 RISCV_PTR test_kprobes_c_jr_addr1 @@ -220,7 +245,9 @@ SYM_DATA_START(test_kprobes_functions) RISCV_PTR test_kprobes_jalr RISCV_PTR test_kprobes_auipc RISCV_PTR test_kprobes_branch + RISCV_PTR test_kprobes_nop #ifdef CONFIG_RISCV_ISA_C + RISCV_PTR test_kprobes_c_nop RISCV_PTR test_kprobes_c_j RISCV_PTR test_kprobes_c_jr RISCV_PTR test_kprobes_c_jalr -- 2.43.0 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] riscv: kprobes: add nop and c.nop to the KUnit test 2026-08-19 10:14 ` [PATCH 2/2] riscv: kprobes: add nop and c.nop to the KUnit test Xiaofeng Yuan @ 2026-08-19 11:58 ` Nam Cao 0 siblings, 0 replies; 6+ messages in thread From: Nam Cao @ 2026-08-19 11:58 UTC (permalink / raw) To: Xiaofeng Yuan, Paul Walmsley, Palmer Dabbelt Cc: Albert Ou, Nam Cao, linux-riscv, yuanxiaofeng Xiaofeng Yuan <yuanxiaofeng@eswincomputing.com> writes: > +SYM_FUNC_START(test_kprobes_nop) > + .option push > + .option norvc > +test_kprobes_nop_addr: > + nop > + .option pop > + li a0, KPROBE_TEST_MAGIC_LOWER > + li a1, KPROBE_TEST_MAGIC_UPPER I split the magic number into _LOWER and _UPPER because I wanted to validate that two instructions in two different code paths are both executed. For this simple case, we can just use KPROBE_TEST_MAGIC. Nam _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 0/2] riscv: kprobes: simulate nop and c.nop instructions @ 2026-08-19 10:26 Xiaofeng Yuan 2026-08-19 10:26 ` [PATCH 2/2] riscv: kprobes: add nop and c.nop to the KUnit test Xiaofeng Yuan 0 siblings, 1 reply; 6+ messages in thread From: Xiaofeng Yuan @ 2026-08-19 10:26 UTC (permalink / raw) To: linux-kernel nop and c.nop have no architectural effect, so handling them through an out-of-line instruction slot and single-stepping is pure overhead. This series simulates them directly in the breakpoint handler by advancing the program counter, following the approach already used on arm64, and extends the RISC-V kprobes KUnit test to cover both paths. Patch 1 adds the simulation. Patch 2 extends the KUnit test with test_kprobes_nop and test_kprobes_c_nop. Verified by cross-compiling for RISC-V and running the kprobes KUnit test in QEMU (ok 1 kprobes_riscv). Xiaofeng Yuan (2): riscv: kprobes: simulate nop and c.nop instructions riscv: kprobes: add nop and c.nop to the KUnit test arch/riscv/include/asm/insn.h | 11 ++++++++ arch/riscv/kernel/probes/decode-insn.c | 6 +++++ arch/riscv/kernel/probes/simulate-insn.c | 14 ++++++++++ arch/riscv/kernel/probes/simulate-insn.h | 2 ++ .../kernel/tests/kprobes/test-kprobes-asm.S | 27 +++++++++++++++++++ 5 files changed, 60 insertions(+) -- 2.43.0 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2] riscv: kprobes: add nop and c.nop to the KUnit test 2026-08-19 10:26 [PATCH 0/2] riscv: kprobes: simulate nop and c.nop instructions Xiaofeng Yuan @ 2026-08-19 10:26 ` Xiaofeng Yuan 0 siblings, 0 replies; 6+ messages in thread From: Xiaofeng Yuan @ 2026-08-19 10:26 UTC (permalink / raw) To: linux-kernel Extend the RISC-V kprobes KUnit test with test_kprobes_nop and test_kprobes_c_nop, covering both the 32-bit nop and the compressed c.nop simulation paths. Signed-off-by: Xiaofeng Yuan <yuanxiaofeng@eswincomputing.com> --- .../kernel/tests/kprobes/test-kprobes-asm.S | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S b/arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S index f16deee9e0..8d8f460cb6 100644 --- a/arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S +++ b/arch/riscv/kernel/tests/kprobes/test-kprobes-asm.S @@ -181,6 +181,29 @@ SYM_FUNC_END(test_kprobes_c_bnez) #endif /* CONFIG_RISCV_ISA_C */ +SYM_FUNC_START(test_kprobes_nop) + .option push + .option norvc +test_kprobes_nop_addr: + nop + .option pop + li a0, KPROBE_TEST_MAGIC_LOWER + li a1, KPROBE_TEST_MAGIC_UPPER + add a0, a0, a1 + ret +SYM_FUNC_END(test_kprobes_nop) + +#ifdef CONFIG_RISCV_ISA_C +SYM_FUNC_START(test_kprobes_c_nop) +test_kprobes_c_nop_addr: + c.nop + li a0, KPROBE_TEST_MAGIC_LOWER + li a1, KPROBE_TEST_MAGIC_UPPER + add a0, a0, a1 + ret +SYM_FUNC_END(test_kprobes_c_nop) +#endif /* CONFIG_RISCV_ISA_C */ + .section .rodata SYM_DATA_START(test_kprobes_addresses) RISCV_PTR test_kprobes_add_addr1 @@ -197,7 +220,9 @@ SYM_DATA_START(test_kprobes_addresses) RISCV_PTR test_kprobes_branch_addr6 RISCV_PTR test_kprobes_branch_addr7 RISCV_PTR test_kprobes_branch_addr8 + RISCV_PTR test_kprobes_nop_addr #ifdef CONFIG_RISCV_ISA_C + RISCV_PTR test_kprobes_c_nop_addr RISCV_PTR test_kprobes_branch_c_j_addr1 RISCV_PTR test_kprobes_branch_c_j_addr2 RISCV_PTR test_kprobes_c_jr_addr1 @@ -220,7 +245,9 @@ SYM_DATA_START(test_kprobes_functions) RISCV_PTR test_kprobes_jalr RISCV_PTR test_kprobes_auipc RISCV_PTR test_kprobes_branch + RISCV_PTR test_kprobes_nop #ifdef CONFIG_RISCV_ISA_C + RISCV_PTR test_kprobes_c_nop RISCV_PTR test_kprobes_c_j RISCV_PTR test_kprobes_c_jr RISCV_PTR test_kprobes_c_jalr -- 2.43.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-08-19 11:58 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-08-19 10:14 [PATCH 0/2] riscv: kprobes: simulate nop and c.nop instructions Xiaofeng Yuan 2026-08-19 10:14 ` [PATCH 1/2] " Xiaofeng Yuan 2026-08-19 11:54 ` Nam Cao 2026-08-19 10:14 ` [PATCH 2/2] riscv: kprobes: add nop and c.nop to the KUnit test Xiaofeng Yuan 2026-08-19 11:58 ` Nam Cao -- strict thread matches above, loose matches on Subject: below -- 2026-08-19 10:26 [PATCH 0/2] riscv: kprobes: simulate nop and c.nop instructions Xiaofeng Yuan 2026-08-19 10:26 ` [PATCH 2/2] riscv: kprobes: add nop and c.nop to the KUnit test Xiaofeng Yuan
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.