1 /* SPDX-License-Identifier: GPL-2.0-only */
2 #ifndef __ASM_LOONGARCH_KPROBES_H
3 #define __ASM_LOONGARCH_KPROBES_H
4 
5 #include <asm-generic/kprobes.h>
6 
7 #ifdef CONFIG_KPROBES
8 
9 #include <asm/inst.h>
10 #include <asm/cacheflush.h>
11 
12 #define __ARCH_WANT_KPROBES_INSN_SLOT
13 #define MAX_INSN_SIZE			2
14 
15 #define flush_insn_slot(p)						\
16 do {									\
17 	if (p->addr)							\
18 		flush_icache_range((unsigned long)p->addr,		\
19 			   (unsigned long)p->addr +			\
20 			   (MAX_INSN_SIZE * sizeof(kprobe_opcode_t)));	\
21 } while (0)
22 
23 #define kretprobe_blacklist_size	0
24 
25 typedef union loongarch_instruction kprobe_opcode_t;
26 
27 /* Architecture specific copy of original instruction */
28 struct arch_specific_insn {
29 	/* copy of the original instruction */
30 	kprobe_opcode_t *insn;
31 	/* restore address after simulation */
32 	unsigned long restore;
33 };
34 
35 struct prev_kprobe {
36 	struct kprobe *kp;
37 	unsigned int status;
38 };
39 
40 /* per-cpu kprobe control block */
41 struct kprobe_ctlblk {
42 	unsigned int kprobe_status;
43 	unsigned long saved_status;
44 	struct prev_kprobe prev_kprobe;
45 };
46 
47 void arch_remove_kprobe(struct kprobe *p);
48 bool kprobe_fault_handler(struct pt_regs *regs, int trapnr);
49 bool kprobe_breakpoint_handler(struct pt_regs *regs);
50 bool kprobe_singlestep_handler(struct pt_regs *regs);
51 
52 void __kretprobe_trampoline(void);
53 void *trampoline_probe_handler(struct pt_regs *regs);
54 
55 #else /* !CONFIG_KPROBES */
56 
57 static inline bool kprobe_breakpoint_handler(struct pt_regs *regs) { return false; }
58 static inline bool kprobe_singlestep_handler(struct pt_regs *regs) { return false; }
59 
60 #endif /* CONFIG_KPROBES */
61 #endif /* __ASM_LOONGARCH_KPROBES_H */
62