1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2018 The FreeBSD Foundation
5 *
6 * This software was developed by Konstantin Belousov <kib@FreeBSD.org>
7 * under sponsorship from the FreeBSD Foundation.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * $FreeBSD$
31 */
32
33 #include <machine/asmacros.h>
34 #include <machine/cputypes.h>
35 #include <machine/pmap.h>
36 #include <machine/specialreg.h>
37
38 #include "assym.inc"
39
40 /*
41 * Fast path for copyout code. We switch to user space %cr3 and perform
42 * move operation between user memory and copyout buffer, located in the
43 * trampoline area. We must switch to trampoline stack, because both
44 * user and kernel buffer accesses might cause page fault.
45 *
46 * Page fault handler expects %edx to point to the onfault routine.
47 * Handler switches to idlePTD and calls the routine.
48 * The routine must restore the stack, enable interrupts, and
49 * return to the caller, informing it about failure.
50 */
51 .text
52
53 ENTRY(copyout_fast)
54 pushl %ebp
55 movl %esp, %ebp
56 pushl %esi
57 pushl %edi
58 pushl %ebx
59
60 movl 20(%ebp),%ebx /* KCR3 */
61 /* bcopy(%esi = kaddr, %edi = PCPU(copyout_buf), %ecx = len) */
62 movl 16(%ebp),%ecx
63 movl 8(%ebp),%esi
64 movl %esp,%eax
65 movl $copyout_fault,%edx
66
67 cli
68 movl PCPU(COPYOUT_BUF),%edi
69 pf_y1: rep; movsb
70
71 movl 16(%ebp),%ecx /* len */
72 movl PCPU(COPYOUT_BUF),%esi /* kaddr */
73 movl 12(%ebp),%edi /* uaddr */
74 movl PCPU(TRAMPSTK),%esp
75 movl PCPU(CURPCB),%edx
76 movl PCB_CR3(%edx),%edx /* UCR3 */
77 movl %edx,%cr3
78 movl $copyout_fault,%edx
79 /* bcopy(%esi = PCPU(copyout_buf), %edi = udaddr, %ecx = len) */
80 pf_x1: rep; movsb
81
82 movl %ebx,%cr3
83 movl %eax,%esp
84 sti
85 xorl %eax,%eax
86 popl %ebx
87 popl %edi
88 popl %esi
89 leave
90 ret
91 END(copyout_fast)
92
93 ENTRY(copyin_fast)
94 pushl %ebp
95 movl %esp, %ebp
96 pushl %esi
97 pushl %edi
98 pushl %ebx
99
100 movl 20(%ebp),%ebx /* KCR3 */
101 movl PCPU(CURPCB),%eax
102 movl PCB_CR3(%eax),%edx /* UCR3 */
103 movl 16(%ebp),%ecx /* len */
104 movl 8(%ebp),%esi /* udaddr */
105 movl %esp,%eax
106
107 cli
108 movl PCPU(COPYOUT_BUF),%edi /* kaddr */
109 movl PCPU(TRAMPSTK),%esp
110 movl %edx,%cr3
111 movl $copyout_fault,%edx
112 /* bcopy(%esi = udaddr, %edi = PCPU(copyout_buf), %ecx = len) */
113 pf_x2: rep; movsb
114
115 movl %ebx,%cr3
116 movl %eax,%esp
117
118 /* bcopy(%esi = PCPU(copyout_buf), %edi = kaddr, %ecx = len) */
119 movl 16(%ebp),%ecx
120 movl 12(%ebp),%edi
121 movl PCPU(COPYOUT_BUF),%esi
122 pf_y2: rep; movsb
123
124 sti
125 xorl %eax,%eax
126 popl %ebx
127 popl %edi
128 popl %esi
129 leave
130 ret
131 END(copyin_fast)
132
133 ALIGN_TEXT
134 copyout_fault:
135 movl %eax,%esp
136 sti
137 movl $EFAULT,%eax
138 popl %ebx
139 popl %edi
140 popl %esi
141 leave
142 ret
143
144 ENTRY(fueword_fast)
145 pushl %ebp
146 movl %esp,%ebp
147 pushl %ebx
148 pushl %esi
149 pushl %edi
150 movl 8(%ebp),%ecx /* from */
151 movl PCPU(CURPCB),%eax
152 movl PCB_CR3(%eax),%eax
153 movl $fusufault,%edx
154 movl 16(%ebp),%ebx
155 movl %esp,%esi
156 cli
157 movl PCPU(TRAMPSTK),%esp
158 movl %eax,%cr3
159 pf_x3: movl (%ecx),%eax
160 movl %ebx,%cr3
161 movl %esi,%esp
162 sti
163 movl 12(%ebp),%edx
164 movl %eax,(%edx)
165 xorl %eax,%eax
166 popl %edi
167 popl %esi
168 popl %ebx
169 leave
170 ret
171 END(fueword_fast)
172
173 ENTRY(fuword16_fast)
174 pushl %ebp
175 movl %esp,%ebp
176 pushl %ebx
177 pushl %esi
178 pushl %edi
179 movl 8(%ebp),%ecx /* from */
180 movl PCPU(CURPCB),%eax
181 movl PCB_CR3(%eax),%eax
182 movl $fusufault,%edx
183 movl 12(%ebp),%ebx
184 movl %esp,%esi
185 cli
186 movl PCPU(TRAMPSTK),%esp
187 movl %eax,%cr3
188 pf_x4: movzwl (%ecx),%eax
189 movl %ebx,%cr3
190 movl %esi,%esp
191 sti
192 popl %edi
193 popl %esi
194 popl %ebx
195 leave
196 ret
197 END(fuword16_fast)
198
199 ENTRY(fubyte_fast)
200 pushl %ebp
201 movl %esp,%ebp
202 pushl %ebx
203 pushl %esi
204 pushl %edi
205 movl 8(%ebp),%ecx /* from */
206 movl PCPU(CURPCB),%eax
207 movl PCB_CR3(%eax),%eax
208 movl $fusufault,%edx
209 movl 12(%ebp),%ebx
210 movl %esp,%esi
211 cli
212 movl PCPU(TRAMPSTK),%esp
213 movl %eax,%cr3
214 pf_x5: movzbl (%ecx),%eax
215 movl %ebx,%cr3
216 movl %esi,%esp
217 sti
218 popl %edi
219 popl %esi
220 popl %ebx
221 leave
222 ret
223 END(fubyte_fast)
224
225 ALIGN_TEXT
226 fusufault:
227 movl %esi,%esp
228 sti
229 xorl %eax,%eax
230 decl %eax
231 popl %edi
232 popl %esi
233 popl %ebx
234 leave
235 ret
236
237 ENTRY(suword_fast)
238 pushl %ebp
239 movl %esp,%ebp
240 pushl %ebx
241 pushl %esi
242 pushl %edi
243 movl PCPU(CURPCB),%eax
244 movl PCB_CR3(%eax),%eax
245 movl $fusufault,%edx
246 movl 8(%ebp),%ecx /* to */
247 movl 12(%ebp),%edi /* val */
248 movl 16(%ebp),%ebx
249 movl %esp,%esi
250 cli
251 movl PCPU(TRAMPSTK),%esp
252 movl %eax,%cr3
253 pf_x6: movl %edi,(%ecx)
254 movl %ebx,%cr3
255 movl %esi,%esp
256 sti
257 xorl %eax,%eax
258 popl %edi
259 popl %esi
260 popl %ebx
261 leave
262 ret
263 END(suword_fast)
264
265 ENTRY(suword16_fast)
266 pushl %ebp
267 movl %esp,%ebp
268 pushl %ebx
269 pushl %esi
270 pushl %edi
271 movl PCPU(CURPCB),%eax
272 movl PCB_CR3(%eax),%eax
273 movl $fusufault,%edx
274 movl 8(%ebp),%ecx /* to */
275 movl 12(%ebp),%edi /* val */
276 movl 16(%ebp),%ebx
277 movl %esp,%esi
278 cli
279 movl PCPU(TRAMPSTK),%esp
280 movl %eax,%cr3
281 pf_x7: movw %di,(%ecx)
282 movl %ebx,%cr3
283 movl %esi,%esp
284 sti
285 xorl %eax,%eax
286 popl %edi
287 popl %esi
288 popl %ebx
289 leave
290 ret
291 END(suword16_fast)
292
293 ENTRY(subyte_fast)
294 pushl %ebp
295 movl %esp,%ebp
296 pushl %ebx
297 pushl %esi
298 pushl %edi
299 movl PCPU(CURPCB),%eax
300 movl PCB_CR3(%eax),%eax
301 movl $fusufault,%edx
302 movl 8(%ebp),%ecx /* to */
303 movl 12(%ebp),%edi /* val */
304 movl 16(%ebp),%ebx
305 movl %esp,%esi
306 cli
307 movl PCPU(TRAMPSTK),%esp
308 movl %eax,%cr3
309 movl %edi,%eax
310 pf_x8: movb %al,(%ecx)
311 movl %ebx,%cr3
312 movl %esi,%esp
313 sti
314 xorl %eax,%eax
315 popl %edi
316 popl %esi
317 popl %ebx
318 leave
319 ret
320 END(subyte_fast)
Cache object: c4594eb3f4e35a27c6dc5c38ca6c7efc
|