xref: /openbmc/linux/arch/x86/kernel/kprobes/common.h (revision f3a112c0)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2f684199fSMasami Hiramatsu #ifndef __X86_KERNEL_KPROBES_COMMON_H
3f684199fSMasami Hiramatsu #define __X86_KERNEL_KPROBES_COMMON_H
4f684199fSMasami Hiramatsu 
5f684199fSMasami Hiramatsu /* Kprobes and Optprobes common header */
6f684199fSMasami Hiramatsu 
7ee213fc7SJosh Poimboeuf #include <asm/asm.h>
84201311dSPeter Zijlstra #include <asm/frame.h>
9*f3a112c0SMasami Hiramatsu #include <asm/insn.h>
10ee213fc7SJosh Poimboeuf 
11f684199fSMasami Hiramatsu #ifdef CONFIG_X86_64
124201311dSPeter Zijlstra 
13f684199fSMasami Hiramatsu #define SAVE_REGS_STRING			\
14f684199fSMasami Hiramatsu 	/* Skip cs, ip, orig_ax. */		\
15f684199fSMasami Hiramatsu 	"	subq $24, %rsp\n"		\
16f684199fSMasami Hiramatsu 	"	pushq %rdi\n"			\
17f684199fSMasami Hiramatsu 	"	pushq %rsi\n"			\
18f684199fSMasami Hiramatsu 	"	pushq %rdx\n"			\
19f684199fSMasami Hiramatsu 	"	pushq %rcx\n"			\
20f684199fSMasami Hiramatsu 	"	pushq %rax\n"			\
21f684199fSMasami Hiramatsu 	"	pushq %r8\n"			\
22f684199fSMasami Hiramatsu 	"	pushq %r9\n"			\
23f684199fSMasami Hiramatsu 	"	pushq %r10\n"			\
24f684199fSMasami Hiramatsu 	"	pushq %r11\n"			\
25f684199fSMasami Hiramatsu 	"	pushq %rbx\n"			\
264201311dSPeter Zijlstra 	"	pushq %rbp\n"			\
27f684199fSMasami Hiramatsu 	"	pushq %r12\n"			\
28f684199fSMasami Hiramatsu 	"	pushq %r13\n"			\
29f684199fSMasami Hiramatsu 	"	pushq %r14\n"			\
304201311dSPeter Zijlstra 	"	pushq %r15\n"			\
314201311dSPeter Zijlstra 	ENCODE_FRAME_POINTER
324201311dSPeter Zijlstra 
33f684199fSMasami Hiramatsu #define RESTORE_REGS_STRING			\
34f684199fSMasami Hiramatsu 	"	popq %r15\n"			\
35f684199fSMasami Hiramatsu 	"	popq %r14\n"			\
36f684199fSMasami Hiramatsu 	"	popq %r13\n"			\
37f684199fSMasami Hiramatsu 	"	popq %r12\n"			\
38f684199fSMasami Hiramatsu 	"	popq %rbp\n"			\
39f684199fSMasami Hiramatsu 	"	popq %rbx\n"			\
40f684199fSMasami Hiramatsu 	"	popq %r11\n"			\
41f684199fSMasami Hiramatsu 	"	popq %r10\n"			\
42f684199fSMasami Hiramatsu 	"	popq %r9\n"			\
43f684199fSMasami Hiramatsu 	"	popq %r8\n"			\
44f684199fSMasami Hiramatsu 	"	popq %rax\n"			\
45f684199fSMasami Hiramatsu 	"	popq %rcx\n"			\
46f684199fSMasami Hiramatsu 	"	popq %rdx\n"			\
47f684199fSMasami Hiramatsu 	"	popq %rsi\n"			\
48f684199fSMasami Hiramatsu 	"	popq %rdi\n"			\
49f684199fSMasami Hiramatsu 	/* Skip orig_ax, ip, cs */		\
50f684199fSMasami Hiramatsu 	"	addq $24, %rsp\n"
51f684199fSMasami Hiramatsu #else
524201311dSPeter Zijlstra 
53f684199fSMasami Hiramatsu #define SAVE_REGS_STRING			\
54f684199fSMasami Hiramatsu 	/* Skip cs, ip, orig_ax and gs. */	\
554201311dSPeter Zijlstra 	"	subl $4*4, %esp\n"		\
56f684199fSMasami Hiramatsu 	"	pushl %fs\n"			\
57f684199fSMasami Hiramatsu 	"	pushl %es\n"			\
58f684199fSMasami Hiramatsu 	"	pushl %ds\n"			\
59f684199fSMasami Hiramatsu 	"	pushl %eax\n"			\
604201311dSPeter Zijlstra 	"	pushl %ebp\n"			\
61f684199fSMasami Hiramatsu 	"	pushl %edi\n"			\
62f684199fSMasami Hiramatsu 	"	pushl %esi\n"			\
63f684199fSMasami Hiramatsu 	"	pushl %edx\n"			\
64f684199fSMasami Hiramatsu 	"	pushl %ecx\n"			\
654201311dSPeter Zijlstra 	"	pushl %ebx\n"			\
664201311dSPeter Zijlstra 	ENCODE_FRAME_POINTER
674201311dSPeter Zijlstra 
68f684199fSMasami Hiramatsu #define RESTORE_REGS_STRING			\
69f684199fSMasami Hiramatsu 	"	popl %ebx\n"			\
70f684199fSMasami Hiramatsu 	"	popl %ecx\n"			\
71f684199fSMasami Hiramatsu 	"	popl %edx\n"			\
72f684199fSMasami Hiramatsu 	"	popl %esi\n"			\
73f684199fSMasami Hiramatsu 	"	popl %edi\n"			\
74f684199fSMasami Hiramatsu 	"	popl %ebp\n"			\
75f684199fSMasami Hiramatsu 	"	popl %eax\n"			\
763c88c692SPeter Zijlstra 	/* Skip ds, es, fs, gs, orig_ax, ip, and cs. */\
773c88c692SPeter Zijlstra 	"	addl $7*4, %esp\n"
78f684199fSMasami Hiramatsu #endif
79f684199fSMasami Hiramatsu 
80f684199fSMasami Hiramatsu /* Ensure if the instruction can be boostable */
81a8d11cd0SMasami Hiramatsu extern int can_boost(struct insn *insn, void *orig_addr);
82f684199fSMasami Hiramatsu /* Recover instruction if given address is probed */
83f684199fSMasami Hiramatsu extern unsigned long recover_probed_instruction(kprobe_opcode_t *buf,
84f684199fSMasami Hiramatsu 					 unsigned long addr);
85f684199fSMasami Hiramatsu /*
86f684199fSMasami Hiramatsu  * Copy an instruction and adjust the displacement if the instruction
87f684199fSMasami Hiramatsu  * uses the %rip-relative addressing mode.
88f684199fSMasami Hiramatsu  */
8963fef14fSMasami Hiramatsu extern int __copy_instruction(u8 *dest, u8 *src, u8 *real, struct insn *insn);
90f684199fSMasami Hiramatsu 
91f684199fSMasami Hiramatsu /* Generate a relative-jump/call instruction */
9263fef14fSMasami Hiramatsu extern void synthesize_reljump(void *dest, void *from, void *to);
9363fef14fSMasami Hiramatsu extern void synthesize_relcall(void *dest, void *from, void *to);
94f684199fSMasami Hiramatsu 
95f684199fSMasami Hiramatsu #ifdef	CONFIG_OPTPROBES
96f684199fSMasami Hiramatsu extern int setup_detour_execution(struct kprobe *p, struct pt_regs *regs, int reenter);
97f684199fSMasami Hiramatsu extern unsigned long __recover_optprobed_insn(kprobe_opcode_t *buf, unsigned long addr);
98f684199fSMasami Hiramatsu #else	/* !CONFIG_OPTPROBES */
setup_detour_execution(struct kprobe * p,struct pt_regs * regs,int reenter)99f684199fSMasami Hiramatsu static inline int setup_detour_execution(struct kprobe *p, struct pt_regs *regs, int reenter)
100f684199fSMasami Hiramatsu {
101f684199fSMasami Hiramatsu 	return 0;
102f684199fSMasami Hiramatsu }
__recover_optprobed_insn(kprobe_opcode_t * buf,unsigned long addr)103f684199fSMasami Hiramatsu static inline unsigned long __recover_optprobed_insn(kprobe_opcode_t *buf, unsigned long addr)
104f684199fSMasami Hiramatsu {
105f684199fSMasami Hiramatsu 	return addr;
106f684199fSMasami Hiramatsu }
107f684199fSMasami Hiramatsu #endif
108f684199fSMasami Hiramatsu 
109f684199fSMasami Hiramatsu #endif
110