42f0cdd20bafcfaf62f1d071ea8c60c2f319a494
[firefly-linux-kernel-4.4.55.git] / arch / x86 / kernel / mcount_64.S
1 /*
2  *  linux/arch/x86_64/mcount_64.S
3  *
4  *  Copyright (C) 2014  Steven Rostedt, Red Hat Inc
5  */
6
7 #include <linux/linkage.h>
8 #include <asm/ptrace.h>
9 #include <asm/ftrace.h>
10
11
12         .code64
13         .section .entry.text, "ax"
14
15
16 #ifdef CONFIG_FUNCTION_TRACER
17
18 #ifdef CC_USING_FENTRY
19 # define function_hook  __fentry__
20 #else
21 # define function_hook  mcount
22 #endif
23
24 #ifdef CONFIG_DYNAMIC_FTRACE
25
26 ENTRY(function_hook)
27         retq
28 END(function_hook)
29
30 /* skip is set if stack has been adjusted */
31 .macro ftrace_caller_setup trace_label skip=0
32         MCOUNT_SAVE_FRAME \skip
33
34         /* Save this location */
35 GLOBAL(\trace_label)
36         /* Load the ftrace_ops into the 3rd parameter */
37         movq function_trace_op(%rip), %rdx
38
39         /* Load ip into the first parameter */
40         movq RIP(%rsp), %rdi
41         subq $MCOUNT_INSN_SIZE, %rdi
42         /* Load the parent_ip into the second parameter */
43 #ifdef CC_USING_FENTRY
44         movq SS+16(%rsp), %rsi
45 #else
46         movq 8(%rbp), %rsi
47 #endif
48 .endm
49
50 ENTRY(ftrace_caller)
51         ftrace_caller_setup ftrace_caller_op_ptr
52         /* regs go into 4th parameter (but make it NULL) */
53         movq $0, %rcx
54
55 GLOBAL(ftrace_call)
56         call ftrace_stub
57
58         MCOUNT_RESTORE_FRAME
59
60         /*
61          * The copied trampoline must call ftrace_return as it
62          * still may need to call the function graph tracer.
63          */
64 GLOBAL(ftrace_caller_end)
65
66 GLOBAL(ftrace_return)
67
68 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
69 GLOBAL(ftrace_graph_call)
70         jmp ftrace_stub
71 #endif
72
73 GLOBAL(ftrace_stub)
74         retq
75 END(ftrace_caller)
76
77 ENTRY(ftrace_regs_caller)
78         /* Save the current flags before compare (in SS location)*/
79         pushfq
80
81         /* skip=8 to skip flags saved in SS */
82         ftrace_caller_setup ftrace_regs_caller_op_ptr 8
83
84         /* Save the rest of pt_regs */
85         movq %r15, R15(%rsp)
86         movq %r14, R14(%rsp)
87         movq %r13, R13(%rsp)
88         movq %r12, R12(%rsp)
89         movq %r11, R11(%rsp)
90         movq %r10, R10(%rsp)
91         movq %rbp, RBP(%rsp)
92         movq %rbx, RBX(%rsp)
93         /* Copy saved flags */
94         movq SS(%rsp), %rcx
95         movq %rcx, EFLAGS(%rsp)
96         /* Kernel segments */
97         movq $__KERNEL_DS, %rcx
98         movq %rcx, SS(%rsp)
99         movq $__KERNEL_CS, %rcx
100         movq %rcx, CS(%rsp)
101         /* Stack - skipping return address */
102         leaq SS+16(%rsp), %rcx
103         movq %rcx, RSP(%rsp)
104
105         /* regs go into 4th parameter */
106         leaq (%rsp), %rcx
107
108 GLOBAL(ftrace_regs_call)
109         call ftrace_stub
110
111         /* Copy flags back to SS, to restore them */
112         movq EFLAGS(%rsp), %rax
113         movq %rax, SS(%rsp)
114
115         /* Handlers can change the RIP */
116         movq RIP(%rsp), %rax
117         movq %rax, SS+8(%rsp)
118
119         /* restore the rest of pt_regs */
120         movq R15(%rsp), %r15
121         movq R14(%rsp), %r14
122         movq R13(%rsp), %r13
123         movq R12(%rsp), %r12
124         movq R10(%rsp), %r10
125         movq RBP(%rsp), %rbp
126         movq RBX(%rsp), %rbx
127
128         /* skip=8 to skip flags saved in SS */
129         MCOUNT_RESTORE_FRAME 8
130
131         /* Restore flags */
132         popfq
133
134         /*
135          * As this jmp to ftrace_return can be a short jump
136          * it must not be copied into the trampoline.
137          * The trampoline will add the code to jump
138          * to the return.
139          */
140 GLOBAL(ftrace_regs_caller_end)
141
142         jmp ftrace_return
143
144         popfq
145         jmp  ftrace_stub
146
147 END(ftrace_regs_caller)
148
149
150 #else /* ! CONFIG_DYNAMIC_FTRACE */
151
152 ENTRY(function_hook)
153         cmpq $ftrace_stub, ftrace_trace_function
154         jnz trace
155
156 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
157         cmpq $ftrace_stub, ftrace_graph_return
158         jnz ftrace_graph_caller
159
160         cmpq $ftrace_graph_entry_stub, ftrace_graph_entry
161         jnz ftrace_graph_caller
162 #endif
163
164 GLOBAL(ftrace_stub)
165         retq
166
167 trace:
168         MCOUNT_SAVE_FRAME
169
170         movq RIP(%rsp), %rdi
171 #ifdef CC_USING_FENTRY
172         movq SS+16(%rsp), %rsi
173 #else
174         movq 8(%rbp), %rsi
175 #endif
176         subq $MCOUNT_INSN_SIZE, %rdi
177
178         call   *ftrace_trace_function
179
180         MCOUNT_RESTORE_FRAME
181
182         jmp ftrace_stub
183 END(function_hook)
184 #endif /* CONFIG_DYNAMIC_FTRACE */
185 #endif /* CONFIG_FUNCTION_TRACER */
186
187 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
188 ENTRY(ftrace_graph_caller)
189         MCOUNT_SAVE_FRAME
190
191 #ifdef CC_USING_FENTRY
192         leaq SS+16(%rsp), %rdi
193         movq $0, %rdx   /* No framepointers needed */
194 #else
195         leaq 8(%rbp), %rdi
196         movq (%rbp), %rdx
197 #endif
198         movq RIP(%rsp), %rsi
199         subq $MCOUNT_INSN_SIZE, %rsi
200
201         call    prepare_ftrace_return
202
203         MCOUNT_RESTORE_FRAME
204
205         retq
206 END(ftrace_graph_caller)
207
208 GLOBAL(return_to_handler)
209         subq  $24, %rsp
210
211         /* Save the return values */
212         movq %rax, (%rsp)
213         movq %rdx, 8(%rsp)
214         movq %rbp, %rdi
215
216         call ftrace_return_to_handler
217
218         movq %rax, %rdi
219         movq 8(%rsp), %rdx
220         movq (%rsp), %rax
221         addq $24, %rsp
222         jmp *%rdi
223 #endif