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