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