[PATCH 3/3] riscv: kgdb: clear bit 0 of single-step jump targets

Clément Léger clement.leger at linux.dev
Thu Nov 12 23:16:14 PST 2026


Per the RISC-V ISA, JALR (and C.JR/C.JALR) clear the lowest bit of
the calculated target address, so that auxiliary information can be
stored in the low bit of function pointers. kgdb's software single
step must compute the same target the hardware will actually take.

This mirrors what the kprobe instruction simulator already does in
simulate_jalr().

Signed-off-by: Clément Léger <clement.leger at linux.dev>
---
 arch/riscv/kernel/kgdb.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/kernel/kgdb.c b/arch/riscv/kernel/kgdb.c
index 121dae87dc68..647560194d8c 100644
--- a/arch/riscv/kernel/kgdb.c
+++ b/arch/riscv/kernel/kgdb.c
@@ -48,7 +48,7 @@ static int get_step_address(struct pt_regs *regs, unsigned long *next_addr)
 		if (riscv_insn_is_c_jalr(op_code) ||
 		    riscv_insn_is_c_jr(op_code)) {
 			rs1_num = decode_register_index(op_code, RVC_C2_RS1_OPOFF);
-			*next_addr = regs_ptr[rs1_num];
+			*next_addr = regs_ptr[rs1_num] & ~1UL;
 		} else if (riscv_insn_is_c_j(op_code) ||
 			   riscv_insn_is_c_jal(op_code)) {
 			*next_addr = RVC_EXTRACT_JTYPE_IMM(op_code) + pc;
@@ -109,6 +109,7 @@ static int get_step_address(struct pt_regs *regs, unsigned long *next_addr)
 			if (rs1_num)
 				*next_addr = ((unsigned long *)regs)[rs1_num];
 			*next_addr += RV_EXTRACT_ITYPE_IMM(op_code);
+			*next_addr &= ~1UL;
 		} else if (riscv_insn_is_sret(op_code)) {
 			*next_addr = pc;
 		} else {
-- 
2.55.0




More information about the linux-riscv mailing list