Unverified Commit a9389297 authored by Nam Cao's avatar Nam Cao Committed by Palmer Dabbelt
Browse files

riscv: kprobes: simulate c.j instruction

parent 06c2afb8
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -29,13 +29,14 @@ 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_j,		insn);
	RISCV_INSN_REJECTED(c_jr,		insn);
	RISCV_INSN_REJECTED(c_jal,		insn);
	RISCV_INSN_REJECTED(c_jalr,		insn);
	RISCV_INSN_REJECTED(c_beqz,		insn);
	RISCV_INSN_REJECTED(c_bnez,		insn);
	RISCV_INSN_REJECTED(c_ebreak,		insn);

	RISCV_INSN_SET_SIMULATE(c_j,		insn);
#endif

	RISCV_INSN_SET_SIMULATE(jal,		insn);
+24 −0
Original line number Diff line number Diff line
@@ -188,3 +188,27 @@ bool __kprobes simulate_branch(u32 opcode, unsigned long addr, struct pt_regs *r

	return true;
}

bool __kprobes simulate_c_j(u32 opcode, unsigned long addr, struct pt_regs *regs)
{
	/*
	 *  15    13 12                            2 1      0
	 * | funct3 | offset[11|4|9:8|10|6|7|3:1|5] | opcode |
	 *     3                   11                    2
	 */

	s32 offset;

	offset  = ((opcode >> 3)  & 0x7) << 1;
	offset |= ((opcode >> 11) & 0x1) << 4;
	offset |= ((opcode >> 2)  & 0x1) << 5;
	offset |= ((opcode >> 7)  & 0x1) << 6;
	offset |= ((opcode >> 6)  & 0x1) << 7;
	offset |= ((opcode >> 9)  & 0x3) << 8;
	offset |= ((opcode >> 8)  & 0x1) << 10;
	offset |= ((opcode >> 12) & 0x1) << 11;

	instruction_pointer_set(regs, addr + sign_extend32(offset, 11));

	return true;
}
+1 −0
Original line number Diff line number Diff line
@@ -24,5 +24,6 @@ bool simulate_auipc(u32 opcode, unsigned long addr, struct pt_regs *regs);
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);

#endif /* _RISCV_KERNEL_PROBES_SIMULATE_INSN_H */