1
2
3
4
5
6 #include <linux/linkage.h>
7 #include <asm/ptrace.h>
8 #include <asm/ftrace.h>
9 #include <asm/export.h>
10 #include <asm/nospec-branch.h>
11 #include <asm/unwind_hints.h>
12 #include <asm/frame.h>
13
14 .code64
15 .section .entry.text, "ax"
16
17 # define function_hook __fentry__
18 EXPORT_SYMBOL(__fentry__)
19
20 #ifdef CONFIG_FRAME_POINTER
21
22 # define MCOUNT_FRAME_SIZE (8+16*2)
23 #else
24
25 # define MCOUNT_FRAME_SIZE 0
26 #endif
27
28
29 #define MCOUNT_REG_SIZE (SS+8 + MCOUNT_FRAME_SIZE)
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 .macro save_mcount_regs added=0
57
58 #ifdef CONFIG_FRAME_POINTER
59
60 pushq %rbp
61
62
63
64
65
66
67
68
69
70
71 pushq \added+8*2(%rsp)
72 pushq %rbp
73 movq %rsp, %rbp
74
75 pushq \added+8*3(%rsp)
76 pushq %rbp
77 movq %rsp, %rbp
78 #endif
79
80
81
82
83 subq $(MCOUNT_REG_SIZE - MCOUNT_FRAME_SIZE), %rsp
84 movq %rax, RAX(%rsp)
85 movq %rcx, RCX(%rsp)
86 movq %rdx, RDX(%rsp)
87 movq %rsi, RSI(%rsp)
88 movq %rdi, RDI(%rsp)
89 movq %r8, R8(%rsp)
90 movq %r9, R9(%rsp)
91
92
93
94
95 #ifdef CONFIG_FRAME_POINTER
96 movq MCOUNT_REG_SIZE-8(%rsp), %rdx
97 #else
98 movq %rbp, %rdx
99 #endif
100 movq %rdx, RBP(%rsp)
101
102
103 movq MCOUNT_REG_SIZE+8+\added(%rsp), %rsi
104
105
106 movq MCOUNT_REG_SIZE+\added(%rsp), %rdi
107 movq %rdi, RIP(%rsp)
108
109
110
111
112
113
114 subq $MCOUNT_INSN_SIZE, %rdi
115 .endm
116
117 .macro restore_mcount_regs
118 movq R9(%rsp), %r9
119 movq R8(%rsp), %r8
120 movq RDI(%rsp), %rdi
121 movq RSI(%rsp), %rsi
122 movq RDX(%rsp), %rdx
123 movq RCX(%rsp), %rcx
124 movq RAX(%rsp), %rax
125
126
127 movq RBP(%rsp), %rbp
128
129 addq $MCOUNT_REG_SIZE, %rsp
130
131 .endm
132
133 #ifdef CONFIG_DYNAMIC_FTRACE
134
135 ENTRY(function_hook)
136 retq
137 ENDPROC(function_hook)
138
139 ENTRY(ftrace_caller)
140
141 save_mcount_regs
142
143 GLOBAL(ftrace_caller_op_ptr)
144
145 movq function_trace_op(%rip), %rdx
146
147
148 movq $0, %rcx
149
150 GLOBAL(ftrace_call)
151 call ftrace_stub
152
153 restore_mcount_regs
154
155
156
157
158
159
160 GLOBAL(ftrace_epilogue)
161
162 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
163 GLOBAL(ftrace_graph_call)
164 jmp ftrace_stub
165 #endif
166
167
168
169
170
171 WEAK(ftrace_stub)
172 retq
173 ENDPROC(ftrace_caller)
174
175 ENTRY(ftrace_regs_caller)
176
177 pushfq
178
179
180 save_mcount_regs 8
181
182
183 GLOBAL(ftrace_regs_caller_op_ptr)
184
185 movq function_trace_op(%rip), %rdx
186
187
188 movq %r15, R15(%rsp)
189 movq %r14, R14(%rsp)
190 movq %r13, R13(%rsp)
191 movq %r12, R12(%rsp)
192 movq %r11, R11(%rsp)
193 movq %r10, R10(%rsp)
194 movq %rbx, RBX(%rsp)
195
196 movq MCOUNT_REG_SIZE(%rsp), %rcx
197 movq %rcx, EFLAGS(%rsp)
198
199 movq $__KERNEL_DS, %rcx
200 movq %rcx, SS(%rsp)
201 movq $__KERNEL_CS, %rcx
202 movq %rcx, CS(%rsp)
203
204 leaq MCOUNT_REG_SIZE+8*2(%rsp), %rcx
205 movq %rcx, RSP(%rsp)
206
207 ENCODE_FRAME_POINTER
208
209
210 leaq (%rsp), %rcx
211
212 GLOBAL(ftrace_regs_call)
213 call ftrace_stub
214
215
216 movq EFLAGS(%rsp), %rax
217 movq %rax, MCOUNT_REG_SIZE(%rsp)
218
219
220 movq RIP(%rsp), %rax
221 movq %rax, MCOUNT_REG_SIZE+8(%rsp)
222
223
224 movq R15(%rsp), %r15
225 movq R14(%rsp), %r14
226 movq R13(%rsp), %r13
227 movq R12(%rsp), %r12
228 movq R10(%rsp), %r10
229 movq RBX(%rsp), %rbx
230
231 restore_mcount_regs
232
233
234 popfq
235
236
237
238
239
240
241
242 GLOBAL(ftrace_regs_caller_end)
243
244 jmp ftrace_epilogue
245
246 ENDPROC(ftrace_regs_caller)
247
248
249 #else
250
251 ENTRY(function_hook)
252 cmpq $ftrace_stub, ftrace_trace_function
253 jnz trace
254
255 fgraph_trace:
256 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
257 cmpq $ftrace_stub, ftrace_graph_return
258 jnz ftrace_graph_caller
259
260 cmpq $ftrace_graph_entry_stub, ftrace_graph_entry
261 jnz ftrace_graph_caller
262 #endif
263
264 GLOBAL(ftrace_stub)
265 retq
266
267 trace:
268
269 save_mcount_regs
270
271
272
273
274
275
276
277 movq ftrace_trace_function, %r8
278 CALL_NOSPEC %r8
279 restore_mcount_regs
280
281 jmp fgraph_trace
282 ENDPROC(function_hook)
283 #endif
284
285 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
286 ENTRY(ftrace_graph_caller)
287
288 save_mcount_regs
289
290 leaq MCOUNT_REG_SIZE+8(%rsp), %rsi
291 movq $0, %rdx
292 call prepare_ftrace_return
293
294 restore_mcount_regs
295
296 retq
297 ENDPROC(ftrace_graph_caller)
298
299 ENTRY(return_to_handler)
300 UNWIND_HINT_EMPTY
301 subq $24, %rsp
302
303
304 movq %rax, (%rsp)
305 movq %rdx, 8(%rsp)
306 movq %rbp, %rdi
307
308 call ftrace_return_to_handler
309
310 movq %rax, %rdi
311 movq 8(%rsp), %rdx
312 movq (%rsp), %rax
313 addq $24, %rsp
314 JMP_NOSPEC %rdi
315 END(return_to_handler)
316 #endif