aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/entry_64.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/entry_64.S')
-rw-r--r--arch/x86/kernel/entry_64.S130
1 files changed, 116 insertions, 14 deletions
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 1a8f3cbb6ee3..4f0322e4ecee 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -69,25 +69,51 @@
69 .section .entry.text, "ax" 69 .section .entry.text, "ax"
70 70
71#ifdef CONFIG_FUNCTION_TRACER 71#ifdef CONFIG_FUNCTION_TRACER
72
73#ifdef CC_USING_FENTRY
74# define function_hook __fentry__
75#else
76# define function_hook mcount
77#endif
78
72#ifdef CONFIG_DYNAMIC_FTRACE 79#ifdef CONFIG_DYNAMIC_FTRACE
73ENTRY(mcount) 80
81ENTRY(function_hook)
74 retq 82 retq
75END(mcount) 83END(function_hook)
84
85/* skip is set if stack has been adjusted */
86.macro ftrace_caller_setup skip=0
87 MCOUNT_SAVE_FRAME \skip
88
89 /* Load the ftrace_ops into the 3rd parameter */
90 leaq function_trace_op, %rdx
91
92 /* Load ip into the first parameter */
93 movq RIP(%rsp), %rdi
94 subq $MCOUNT_INSN_SIZE, %rdi
95 /* Load the parent_ip into the second parameter */
96#ifdef CC_USING_FENTRY
97 movq SS+16(%rsp), %rsi
98#else
99 movq 8(%rbp), %rsi
100#endif
101.endm
76 102
77ENTRY(ftrace_caller) 103ENTRY(ftrace_caller)
104 /* Check if tracing was disabled (quick check) */
78 cmpl $0, function_trace_stop 105 cmpl $0, function_trace_stop
79 jne ftrace_stub 106 jne ftrace_stub
80 107
81 MCOUNT_SAVE_FRAME 108 ftrace_caller_setup
82 109 /* regs go into 4th parameter (but make it NULL) */
83 movq 0x38(%rsp), %rdi 110 movq $0, %rcx
84 movq 8(%rbp), %rsi
85 subq $MCOUNT_INSN_SIZE, %rdi
86 111
87GLOBAL(ftrace_call) 112GLOBAL(ftrace_call)
88 call ftrace_stub 113 call ftrace_stub
89 114
90 MCOUNT_RESTORE_FRAME 115 MCOUNT_RESTORE_FRAME
116ftrace_return:
91 117
92#ifdef CONFIG_FUNCTION_GRAPH_TRACER 118#ifdef CONFIG_FUNCTION_GRAPH_TRACER
93GLOBAL(ftrace_graph_call) 119GLOBAL(ftrace_graph_call)
@@ -98,8 +124,78 @@ GLOBAL(ftrace_stub)
98 retq 124 retq
99END(ftrace_caller) 125END(ftrace_caller)
100 126
127ENTRY(ftrace_regs_caller)
128 /* Save the current flags before compare (in SS location)*/
129 pushfq
130
131 /* Check if tracing was disabled (quick check) */
132 cmpl $0, function_trace_stop
133 jne ftrace_restore_flags
134
135 /* skip=8 to skip flags saved in SS */
136 ftrace_caller_setup 8
137
138 /* Save the rest of pt_regs */
139 movq %r15, R15(%rsp)
140 movq %r14, R14(%rsp)
141 movq %r13, R13(%rsp)
142 movq %r12, R12(%rsp)
143 movq %r11, R11(%rsp)
144 movq %r10, R10(%rsp)
145 movq %rbp, RBP(%rsp)
146 movq %rbx, RBX(%rsp)
147 /* Copy saved flags */
148 movq SS(%rsp), %rcx
149 movq %rcx, EFLAGS(%rsp)
150 /* Kernel segments */
151 movq $__KERNEL_DS, %rcx
152 movq %rcx, SS(%rsp)
153 movq $__KERNEL_CS, %rcx
154 movq %rcx, CS(%rsp)
155 /* Stack - skipping return address */
156 leaq SS+16(%rsp), %rcx
157 movq %rcx, RSP(%rsp)
158
159 /* regs go into 4th parameter */
160 leaq (%rsp), %rcx
161
162GLOBAL(ftrace_regs_call)
163 call ftrace_stub
164
165 /* Copy flags back to SS, to restore them */
166 movq EFLAGS(%rsp), %rax
167 movq %rax, SS(%rsp)
168
169 /* Handlers can change the RIP */
170 movq RIP(%rsp), %rax
171 movq %rax, SS+8(%rsp)
172
173 /* restore the rest of pt_regs */
174 movq R15(%rsp), %r15
175 movq R14(%rsp), %r14
176 movq R13(%rsp), %r13
177 movq R12(%rsp), %r12
178 movq R10(%rsp), %r10
179 movq RBP(%rsp), %rbp
180 movq RBX(%rsp), %rbx
181
182 /* skip=8 to skip flags saved in SS */
183 MCOUNT_RESTORE_FRAME 8
184
185 /* Restore flags */
186 popfq
187
188 jmp ftrace_return
189ftrace_restore_flags:
190 popfq
191 jmp ftrace_stub
192
193END(ftrace_regs_caller)
194
195
101#else /* ! CONFIG_DYNAMIC_FTRACE */ 196#else /* ! CONFIG_DYNAMIC_FTRACE */
102ENTRY(mcount) 197
198ENTRY(function_hook)
103 cmpl $0, function_trace_stop 199 cmpl $0, function_trace_stop
104 jne ftrace_stub 200 jne ftrace_stub
105 201
@@ -120,8 +216,12 @@ GLOBAL(ftrace_stub)
120trace: 216trace:
121 MCOUNT_SAVE_FRAME 217 MCOUNT_SAVE_FRAME
122 218
123 movq 0x38(%rsp), %rdi 219 movq RIP(%rsp), %rdi
220#ifdef CC_USING_FENTRY
221 movq SS+16(%rsp), %rsi
222#else
124 movq 8(%rbp), %rsi 223 movq 8(%rbp), %rsi
224#endif
125 subq $MCOUNT_INSN_SIZE, %rdi 225 subq $MCOUNT_INSN_SIZE, %rdi
126 226
127 call *ftrace_trace_function 227 call *ftrace_trace_function
@@ -129,20 +229,22 @@ trace:
129 MCOUNT_RESTORE_FRAME 229 MCOUNT_RESTORE_FRAME
130 230
131 jmp ftrace_stub 231 jmp ftrace_stub
132END(mcount) 232END(function_hook)
133#endif /* CONFIG_DYNAMIC_FTRACE */ 233#endif /* CONFIG_DYNAMIC_FTRACE */
134#endif /* CONFIG_FUNCTION_TRACER */ 234#endif /* CONFIG_FUNCTION_TRACER */
135 235
136#ifdef CONFIG_FUNCTION_GRAPH_TRACER 236#ifdef CONFIG_FUNCTION_GRAPH_TRACER
137ENTRY(ftrace_graph_caller) 237ENTRY(ftrace_graph_caller)
138 cmpl $0, function_trace_stop
139 jne ftrace_stub
140
141 MCOUNT_SAVE_FRAME 238 MCOUNT_SAVE_FRAME
142 239
240#ifdef CC_USING_FENTRY
241 leaq SS+16(%rsp), %rdi
242 movq $0, %rdx /* No framepointers needed */
243#else
143 leaq 8(%rbp), %rdi 244 leaq 8(%rbp), %rdi
144 movq 0x38(%rsp), %rsi
145 movq (%rbp), %rdx 245 movq (%rbp), %rdx
246#endif
247 movq RIP(%rsp), %rsi
146 subq $MCOUNT_INSN_SIZE, %rsi 248 subq $MCOUNT_INSN_SIZE, %rsi
147 249
148 call prepare_ftrace_return 250 call prepare_ftrace_return