1 /* SPDX-License-Identifier: GPL-2.0+ */
2 
3 #ifndef _RISCV_KERNEL_PROBES_SIMULATE_INSN_H
4 #define _RISCV_KERNEL_PROBES_SIMULATE_INSN_H
5 
6 #define __RISCV_INSN_FUNCS(name, mask, val)				\
7 static __always_inline bool riscv_insn_is_##name(probe_opcode_t code)	\
8 {									\
9 	BUILD_BUG_ON(~(mask) & (val));					\
10 	return (code & (mask)) == (val);				\
11 }									\
12 bool simulate_##name(u32 opcode, unsigned long addr,			\
13 		     struct pt_regs *regs)
14 
15 #define RISCV_INSN_REJECTED(name, code)					\
16 	do {								\
17 		if (riscv_insn_is_##name(code)) {			\
18 			return INSN_REJECTED;				\
19 		}							\
20 	} while (0)
21 
22 __RISCV_INSN_FUNCS(system,	0x7f, 0x73);
23 __RISCV_INSN_FUNCS(fence,	0x7f, 0x0f);
24 
25 #define RISCV_INSN_SET_SIMULATE(name, code)				\
26 	do {								\
27 		if (riscv_insn_is_##name(code)) {			\
28 			api->handler = simulate_##name;			\
29 			return INSN_GOOD_NO_SLOT;			\
30 		}							\
31 	} while (0)
32 
33 __RISCV_INSN_FUNCS(c_j,		0xe003, 0xa001);
34 __RISCV_INSN_FUNCS(c_jr,	0xf007, 0x8002);
35 __RISCV_INSN_FUNCS(c_jal,	0xe003, 0x2001);
36 __RISCV_INSN_FUNCS(c_jalr,	0xf007, 0x9002);
37 __RISCV_INSN_FUNCS(c_beqz,	0xe003, 0xc001);
38 __RISCV_INSN_FUNCS(c_bnez,	0xe003, 0xe001);
39 __RISCV_INSN_FUNCS(c_ebreak,	0xffff, 0x9002);
40 
41 __RISCV_INSN_FUNCS(auipc,	0x7f, 0x17);
42 __RISCV_INSN_FUNCS(branch,	0x7f, 0x63);
43 
44 __RISCV_INSN_FUNCS(jal,		0x7f, 0x6f);
45 __RISCV_INSN_FUNCS(jalr,	0x707f, 0x67);
46 
47 #endif /* _RISCV_KERNEL_PROBES_SIMULATE_INSN_H */
48