]>
Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
3d82c59c SRV |
2 | /* |
3 | * Copyright (C) 2017 Steven Rostedt, VMware Inc. | |
4 | */ | |
5 | ||
6 | #include <linux/linkage.h> | |
7 | #include <asm/page_types.h> | |
8 | #include <asm/segment.h> | |
9 | #include <asm/export.h> | |
10 | #include <asm/ftrace.h> | |
9351803b | 11 | #include <asm/nospec-branch.h> |
ea1ed38d | 12 | #include <asm/frame.h> |
3c88c692 | 13 | #include <asm/asm-offsets.h> |
3d82c59c | 14 | |
562e14f7 | 15 | #ifdef CONFIG_FRAME_POINTER |
644e0e8d SRV |
16 | # define MCOUNT_FRAME 1 /* using frame = true */ |
17 | #else | |
18 | # define MCOUNT_FRAME 0 /* using frame = false */ | |
19 | #endif | |
20 | ||
0f42c1ad | 21 | SYM_FUNC_START(__fentry__) |
3d82c59c | 22 | ret |
0f42c1ad BP |
23 | SYM_FUNC_END(__fentry__) |
24 | EXPORT_SYMBOL(__fentry__) | |
3d82c59c | 25 | |
5e63306f | 26 | SYM_CODE_START(ftrace_caller) |
e6928e58 | 27 | |
562e14f7 | 28 | #ifdef CONFIG_FRAME_POINTER |
644e0e8d SRV |
29 | /* |
30 | * Frame pointers are of ip followed by bp. | |
31 | * Since fentry is an immediate jump, we are left with | |
32 | * parent-ip, function-ip. We need to add a frame with | |
33 | * parent-ip followed by ebp. | |
34 | */ | |
35 | pushl 4(%esp) /* parent ip */ | |
e6928e58 SRV |
36 | pushl %ebp |
37 | movl %esp, %ebp | |
644e0e8d | 38 | pushl 2*4(%esp) /* function ip */ |
562e14f7 | 39 | |
644e0e8d SRV |
40 | /* For mcount, the function ip is directly above */ |
41 | pushl %ebp | |
42 | movl %esp, %ebp | |
43 | #endif | |
3d82c59c SRV |
44 | pushl %eax |
45 | pushl %ecx | |
46 | pushl %edx | |
47 | pushl $0 /* Pass NULL as regs pointer */ | |
644e0e8d | 48 | |
562e14f7 | 49 | #ifdef CONFIG_FRAME_POINTER |
644e0e8d | 50 | /* Load parent ebp into edx */ |
e6928e58 | 51 | movl 4*4(%esp), %edx |
644e0e8d SRV |
52 | #else |
53 | /* There's no frame pointer, load the appropriate stack addr instead */ | |
54 | lea 4*4(%esp), %edx | |
55 | #endif | |
56 | ||
57 | movl (MCOUNT_FRAME+4)*4(%esp), %eax /* load the rip */ | |
e6928e58 | 58 | /* Get the parent ip */ |
644e0e8d SRV |
59 | movl 4(%edx), %edx /* edx has ebp */ |
60 | ||
3d82c59c SRV |
61 | movl function_trace_op, %ecx |
62 | subl $MCOUNT_INSN_SIZE, %eax | |
63 | ||
64 | .globl ftrace_call | |
65 | ftrace_call: | |
66 | call ftrace_stub | |
67 | ||
68 | addl $4, %esp /* skip NULL pointer */ | |
69 | popl %edx | |
70 | popl %ecx | |
71 | popl %eax | |
562e14f7 | 72 | #ifdef CONFIG_FRAME_POINTER |
e6928e58 | 73 | popl %ebp |
644e0e8d SRV |
74 | addl $4,%esp /* skip function ip */ |
75 | popl %ebp /* this is the orig bp */ | |
76 | addl $4, %esp /* skip parent ip */ | |
644e0e8d | 77 | #endif |
3d82c59c SRV |
78 | .Lftrace_ret: |
79 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | |
80 | .globl ftrace_graph_call | |
81 | ftrace_graph_call: | |
82 | jmp ftrace_stub | |
83 | #endif | |
84 | ||
85 | /* This is weak to keep gas from relaxing the jumps */ | |
13fbe784 | 86 | SYM_INNER_LABEL_ALIGN(ftrace_stub, SYM_L_WEAK) |
3d82c59c | 87 | ret |
5e63306f | 88 | SYM_CODE_END(ftrace_caller) |
3d82c59c | 89 | |
78762b0e | 90 | SYM_CODE_START(ftrace_regs_caller) |
3d82c59c | 91 | /* |
3c88c692 PZ |
92 | * We're here from an mcount/fentry CALL, and the stack frame looks like: |
93 | * | |
94 | * <previous context> | |
95 | * RET-IP | |
96 | * | |
97 | * The purpose of this function is to call out in an emulated INT3 | |
98 | * environment with a stack frame like: | |
99 | * | |
100 | * <previous context> | |
101 | * gap / RET-IP | |
102 | * gap | |
103 | * gap | |
104 | * gap | |
105 | * pt_regs | |
106 | * | |
107 | * We do _NOT_ restore: ss, flags, cs, gs, fs, es, ds | |
3d82c59c | 108 | */ |
3c88c692 PZ |
109 | subl $3*4, %esp # RET-IP + 3 gaps |
110 | pushl %ss # ss | |
111 | pushl %esp # points at ss | |
112 | addl $5*4, (%esp) # make it point at <previous context> | |
113 | pushfl # flags | |
114 | pushl $__KERNEL_CS # cs | |
115 | pushl 7*4(%esp) # ip <- RET-IP | |
116 | pushl $0 # orig_eax | |
117 | ||
3d82c59c SRV |
118 | pushl %gs |
119 | pushl %fs | |
120 | pushl %es | |
121 | pushl %ds | |
ff04b440 | 122 | |
3c88c692 | 123 | pushl %eax |
3d82c59c SRV |
124 | pushl %ebp |
125 | pushl %edi | |
126 | pushl %esi | |
127 | pushl %edx | |
128 | pushl %ecx | |
129 | pushl %ebx | |
130 | ||
ea1ed38d PZ |
131 | ENCODE_FRAME_POINTER |
132 | ||
3c88c692 PZ |
133 | movl PT_EIP(%esp), %eax # 1st argument: IP |
134 | subl $MCOUNT_INSN_SIZE, %eax | |
135 | movl 21*4(%esp), %edx # 2nd argument: parent ip | |
136 | movl function_trace_op, %ecx # 3rd argument: ftrace_pos | |
137 | pushl %esp # 4th argument: pt_regs | |
3d82c59c | 138 | |
26ba4e57 | 139 | SYM_INNER_LABEL(ftrace_regs_call, SYM_L_GLOBAL) |
3d82c59c SRV |
140 | call ftrace_stub |
141 | ||
3c88c692 | 142 | addl $4, %esp # skip 4th argument |
ff04b440 | 143 | |
3c88c692 PZ |
144 | /* place IP below the new SP */ |
145 | movl PT_OLDESP(%esp), %eax | |
146 | movl PT_EIP(%esp), %ecx | |
147 | movl %ecx, -4(%eax) | |
ff04b440 | 148 | |
3c88c692 PZ |
149 | /* place EAX below that */ |
150 | movl PT_EAX(%esp), %ecx | |
151 | movl %ecx, -8(%eax) | |
3d82c59c SRV |
152 | |
153 | popl %ebx | |
154 | popl %ecx | |
155 | popl %edx | |
156 | popl %esi | |
157 | popl %edi | |
158 | popl %ebp | |
3d82c59c | 159 | |
3c88c692 PZ |
160 | lea -8(%eax), %esp |
161 | popl %eax | |
ff04b440 SRV |
162 | |
163 | jmp .Lftrace_ret | |
78762b0e | 164 | SYM_CODE_END(ftrace_regs_caller) |
3d82c59c SRV |
165 | |
166 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | |
5e63306f | 167 | SYM_CODE_START(ftrace_graph_caller) |
3d82c59c SRV |
168 | pushl %eax |
169 | pushl %ecx | |
170 | pushl %edx | |
644e0e8d SRV |
171 | movl 3*4(%esp), %eax |
172 | /* Even with frame pointers, fentry doesn't have one here */ | |
644e0e8d SRV |
173 | lea 4*4(%esp), %edx |
174 | movl $0, %ecx | |
3d82c59c SRV |
175 | subl $MCOUNT_INSN_SIZE, %eax |
176 | call prepare_ftrace_return | |
177 | popl %edx | |
178 | popl %ecx | |
179 | popl %eax | |
180 | ret | |
5e63306f | 181 | SYM_CODE_END(ftrace_graph_caller) |
3d82c59c SRV |
182 | |
183 | .globl return_to_handler | |
184 | return_to_handler: | |
185 | pushl %eax | |
186 | pushl %edx | |
644e0e8d | 187 | movl $0, %eax |
3d82c59c SRV |
188 | call ftrace_return_to_handler |
189 | movl %eax, %ecx | |
190 | popl %edx | |
191 | popl %eax | |
34fdce69 | 192 | JMP_NOSPEC ecx |
3d82c59c | 193 | #endif |