diff options
Diffstat (limited to 'arch/m32r/lib/usercopy.c')
-rw-r--r-- | arch/m32r/lib/usercopy.c | 362 |
1 files changed, 0 insertions, 362 deletions
diff --git a/arch/m32r/lib/usercopy.c b/arch/m32r/lib/usercopy.c deleted file mode 100644 index 0892a4341b3a..000000000000 --- a/arch/m32r/lib/usercopy.c +++ /dev/null | |||
@@ -1,362 +0,0 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * User address space access functions. | ||
4 | * The non inlined parts of asm-m32r/uaccess.h are here. | ||
5 | * | ||
6 | * Copyright 1997 Andi Kleen <ak@muc.de> | ||
7 | * Copyright 1997 Linus Torvalds | ||
8 | * Copyright 2001, 2002, 2004 Hirokazu Takata | ||
9 | */ | ||
10 | #include <linux/prefetch.h> | ||
11 | #include <linux/string.h> | ||
12 | #include <linux/thread_info.h> | ||
13 | #include <linux/uaccess.h> | ||
14 | |||
15 | /* | ||
16 | * Copy a null terminated string from userspace. | ||
17 | */ | ||
18 | |||
19 | #ifdef CONFIG_ISA_DUAL_ISSUE | ||
20 | |||
21 | #define __do_strncpy_from_user(dst,src,count,res) \ | ||
22 | do { \ | ||
23 | int __d0, __d1, __d2; \ | ||
24 | __asm__ __volatile__( \ | ||
25 | " beqz %1, 2f\n" \ | ||
26 | " .fillinsn\n" \ | ||
27 | "0: ldb r14, @%3 || addi %3, #1\n" \ | ||
28 | " stb r14, @%4 || addi %4, #1\n" \ | ||
29 | " beqz r14, 1f\n" \ | ||
30 | " addi %1, #-1\n" \ | ||
31 | " bnez %1, 0b\n" \ | ||
32 | " .fillinsn\n" \ | ||
33 | "1: sub %0, %1\n" \ | ||
34 | " .fillinsn\n" \ | ||
35 | "2:\n" \ | ||
36 | ".section .fixup,\"ax\"\n" \ | ||
37 | " .balign 4\n" \ | ||
38 | "3: seth r14, #high(2b)\n" \ | ||
39 | " or3 r14, r14, #low(2b)\n" \ | ||
40 | " jmp r14 || ldi %0, #%5\n" \ | ||
41 | ".previous\n" \ | ||
42 | ".section __ex_table,\"a\"\n" \ | ||
43 | " .balign 4\n" \ | ||
44 | " .long 0b,3b\n" \ | ||
45 | ".previous" \ | ||
46 | : "=&r"(res), "=&r"(count), "=&r" (__d0), "=&r" (__d1), \ | ||
47 | "=&r" (__d2) \ | ||
48 | : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), \ | ||
49 | "4"(dst) \ | ||
50 | : "r14", "cbit", "memory"); \ | ||
51 | } while (0) | ||
52 | |||
53 | #else /* not CONFIG_ISA_DUAL_ISSUE */ | ||
54 | |||
55 | #define __do_strncpy_from_user(dst,src,count,res) \ | ||
56 | do { \ | ||
57 | int __d0, __d1, __d2; \ | ||
58 | __asm__ __volatile__( \ | ||
59 | " beqz %1, 2f\n" \ | ||
60 | " .fillinsn\n" \ | ||
61 | "0: ldb r14, @%3\n" \ | ||
62 | " stb r14, @%4\n" \ | ||
63 | " addi %3, #1\n" \ | ||
64 | " addi %4, #1\n" \ | ||
65 | " beqz r14, 1f\n" \ | ||
66 | " addi %1, #-1\n" \ | ||
67 | " bnez %1, 0b\n" \ | ||
68 | " .fillinsn\n" \ | ||
69 | "1: sub %0, %1\n" \ | ||
70 | " .fillinsn\n" \ | ||
71 | "2:\n" \ | ||
72 | ".section .fixup,\"ax\"\n" \ | ||
73 | " .balign 4\n" \ | ||
74 | "3: ldi %0, #%5\n" \ | ||
75 | " seth r14, #high(2b)\n" \ | ||
76 | " or3 r14, r14, #low(2b)\n" \ | ||
77 | " jmp r14\n" \ | ||
78 | ".previous\n" \ | ||
79 | ".section __ex_table,\"a\"\n" \ | ||
80 | " .balign 4\n" \ | ||
81 | " .long 0b,3b\n" \ | ||
82 | ".previous" \ | ||
83 | : "=&r"(res), "=&r"(count), "=&r" (__d0), "=&r" (__d1), \ | ||
84 | "=&r" (__d2) \ | ||
85 | : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), \ | ||
86 | "4"(dst) \ | ||
87 | : "r14", "cbit", "memory"); \ | ||
88 | } while (0) | ||
89 | |||
90 | #endif /* CONFIG_ISA_DUAL_ISSUE */ | ||
91 | |||
92 | long | ||
93 | strncpy_from_user(char *dst, const char __user *src, long count) | ||
94 | { | ||
95 | long res = -EFAULT; | ||
96 | if (access_ok(VERIFY_READ, src, 1)) | ||
97 | __do_strncpy_from_user(dst, src, count, res); | ||
98 | return res; | ||
99 | } | ||
100 | |||
101 | |||
102 | /* | ||
103 | * Zero Userspace | ||
104 | */ | ||
105 | |||
106 | #ifdef CONFIG_ISA_DUAL_ISSUE | ||
107 | |||
108 | #define __do_clear_user(addr,size) \ | ||
109 | do { \ | ||
110 | int __dst, __c; \ | ||
111 | __asm__ __volatile__( \ | ||
112 | " beqz %1, 9f\n" \ | ||
113 | " and3 r14, %0, #3\n" \ | ||
114 | " bnez r14, 2f\n" \ | ||
115 | " and3 r14, %1, #3\n" \ | ||
116 | " bnez r14, 2f\n" \ | ||
117 | " and3 %1, %1, #3\n" \ | ||
118 | " beqz %2, 2f\n" \ | ||
119 | " addi %0, #-4\n" \ | ||
120 | " .fillinsn\n" \ | ||
121 | "0: ; word clear \n" \ | ||
122 | " st %6, @+%0 || addi %2, #-1\n" \ | ||
123 | " bnez %2, 0b\n" \ | ||
124 | " beqz %1, 9f\n" \ | ||
125 | " .fillinsn\n" \ | ||
126 | "2: ; byte clear \n" \ | ||
127 | " stb %6, @%0 || addi %1, #-1\n" \ | ||
128 | " addi %0, #1\n" \ | ||
129 | " bnez %1, 2b\n" \ | ||
130 | " .fillinsn\n" \ | ||
131 | "9:\n" \ | ||
132 | ".section .fixup,\"ax\"\n" \ | ||
133 | " .balign 4\n" \ | ||
134 | "4: slli %2, #2\n" \ | ||
135 | " seth r14, #high(9b)\n" \ | ||
136 | " or3 r14, r14, #low(9b)\n" \ | ||
137 | " jmp r14 || add %1, %2\n" \ | ||
138 | ".previous\n" \ | ||
139 | ".section __ex_table,\"a\"\n" \ | ||
140 | " .balign 4\n" \ | ||
141 | " .long 0b,4b\n" \ | ||
142 | " .long 2b,9b\n" \ | ||
143 | ".previous\n" \ | ||
144 | : "=&r"(__dst), "=&r"(size), "=&r"(__c) \ | ||
145 | : "0"(addr), "1"(size), "2"(size / 4), "r"(0) \ | ||
146 | : "r14", "cbit", "memory"); \ | ||
147 | } while (0) | ||
148 | |||
149 | #else /* not CONFIG_ISA_DUAL_ISSUE */ | ||
150 | |||
151 | #define __do_clear_user(addr,size) \ | ||
152 | do { \ | ||
153 | int __dst, __c; \ | ||
154 | __asm__ __volatile__( \ | ||
155 | " beqz %1, 9f\n" \ | ||
156 | " and3 r14, %0, #3\n" \ | ||
157 | " bnez r14, 2f\n" \ | ||
158 | " and3 r14, %1, #3\n" \ | ||
159 | " bnez r14, 2f\n" \ | ||
160 | " and3 %1, %1, #3\n" \ | ||
161 | " beqz %2, 2f\n" \ | ||
162 | " addi %0, #-4\n" \ | ||
163 | " .fillinsn\n" \ | ||
164 | "0: st %6, @+%0 ; word clear \n" \ | ||
165 | " addi %2, #-1\n" \ | ||
166 | " bnez %2, 0b\n" \ | ||
167 | " beqz %1, 9f\n" \ | ||
168 | " .fillinsn\n" \ | ||
169 | "2: stb %6, @%0 ; byte clear \n" \ | ||
170 | " addi %1, #-1\n" \ | ||
171 | " addi %0, #1\n" \ | ||
172 | " bnez %1, 2b\n" \ | ||
173 | " .fillinsn\n" \ | ||
174 | "9:\n" \ | ||
175 | ".section .fixup,\"ax\"\n" \ | ||
176 | " .balign 4\n" \ | ||
177 | "4: slli %2, #2\n" \ | ||
178 | " add %1, %2\n" \ | ||
179 | " seth r14, #high(9b)\n" \ | ||
180 | " or3 r14, r14, #low(9b)\n" \ | ||
181 | " jmp r14\n" \ | ||
182 | ".previous\n" \ | ||
183 | ".section __ex_table,\"a\"\n" \ | ||
184 | " .balign 4\n" \ | ||
185 | " .long 0b,4b\n" \ | ||
186 | " .long 2b,9b\n" \ | ||
187 | ".previous\n" \ | ||
188 | : "=&r"(__dst), "=&r"(size), "=&r"(__c) \ | ||
189 | : "0"(addr), "1"(size), "2"(size / 4), "r"(0) \ | ||
190 | : "r14", "cbit", "memory"); \ | ||
191 | } while (0) | ||
192 | |||
193 | #endif /* not CONFIG_ISA_DUAL_ISSUE */ | ||
194 | |||
195 | unsigned long | ||
196 | clear_user(void __user *to, unsigned long n) | ||
197 | { | ||
198 | if (access_ok(VERIFY_WRITE, to, n)) | ||
199 | __do_clear_user(to, n); | ||
200 | return n; | ||
201 | } | ||
202 | |||
203 | unsigned long | ||
204 | __clear_user(void __user *to, unsigned long n) | ||
205 | { | ||
206 | __do_clear_user(to, n); | ||
207 | return n; | ||
208 | } | ||
209 | |||
210 | /* | ||
211 | * Return the size of a string (including the ending 0) | ||
212 | * | ||
213 | * Return 0 on exception, a value greater than N if too long | ||
214 | */ | ||
215 | |||
216 | #ifdef CONFIG_ISA_DUAL_ISSUE | ||
217 | |||
218 | long strnlen_user(const char __user *s, long n) | ||
219 | { | ||
220 | unsigned long mask = -__addr_ok(s); | ||
221 | unsigned long res; | ||
222 | |||
223 | __asm__ __volatile__( | ||
224 | " and %0, %5 || mv r1, %1\n" | ||
225 | " beqz %0, strnlen_exit\n" | ||
226 | " and3 r0, %1, #3\n" | ||
227 | " bnez r0, strnlen_byte_loop\n" | ||
228 | " cmpui %0, #4\n" | ||
229 | " bc strnlen_byte_loop\n" | ||
230 | "strnlen_word_loop:\n" | ||
231 | "0: ld r0, @%1+\n" | ||
232 | " pcmpbz r0\n" | ||
233 | " bc strnlen_last_bytes_fixup\n" | ||
234 | " addi %0, #-4\n" | ||
235 | " beqz %0, strnlen_exit\n" | ||
236 | " bgtz %0, strnlen_word_loop\n" | ||
237 | "strnlen_last_bytes:\n" | ||
238 | " mv %0, %4\n" | ||
239 | "strnlen_last_bytes_fixup:\n" | ||
240 | " addi %1, #-4\n" | ||
241 | "strnlen_byte_loop:\n" | ||
242 | "1: ldb r0, @%1 || addi %0, #-1\n" | ||
243 | " beqz r0, strnlen_exit\n" | ||
244 | " addi %1, #1\n" | ||
245 | " bnez %0, strnlen_byte_loop\n" | ||
246 | "strnlen_exit:\n" | ||
247 | " sub %1, r1\n" | ||
248 | " add3 %0, %1, #1\n" | ||
249 | " .fillinsn\n" | ||
250 | "9:\n" | ||
251 | ".section .fixup,\"ax\"\n" | ||
252 | " .balign 4\n" | ||
253 | "4: addi %1, #-4\n" | ||
254 | " .fillinsn\n" | ||
255 | "5: seth r1, #high(9b)\n" | ||
256 | " or3 r1, r1, #low(9b)\n" | ||
257 | " jmp r1 || ldi %0, #0\n" | ||
258 | ".previous\n" | ||
259 | ".section __ex_table,\"a\"\n" | ||
260 | " .balign 4\n" | ||
261 | " .long 0b,4b\n" | ||
262 | " .long 1b,5b\n" | ||
263 | ".previous" | ||
264 | : "=&r" (res), "=r" (s) | ||
265 | : "0" (n), "1" (s), "r" (n & 3), "r" (mask), "r"(0x01010101) | ||
266 | : "r0", "r1", "cbit"); | ||
267 | |||
268 | /* NOTE: strnlen_user() algorithm: | ||
269 | * { | ||
270 | * char *p; | ||
271 | * for (p = s; n-- && *p != '\0'; ++p) | ||
272 | * ; | ||
273 | * return p - s + 1; | ||
274 | * } | ||
275 | */ | ||
276 | |||
277 | /* NOTE: If a null char. exists, return 0. | ||
278 | * if ((x - 0x01010101) & ~x & 0x80808080)\n" | ||
279 | * return 0;\n" | ||
280 | */ | ||
281 | |||
282 | return res & mask; | ||
283 | } | ||
284 | |||
285 | #else /* not CONFIG_ISA_DUAL_ISSUE */ | ||
286 | |||
287 | long strnlen_user(const char __user *s, long n) | ||
288 | { | ||
289 | unsigned long mask = -__addr_ok(s); | ||
290 | unsigned long res; | ||
291 | |||
292 | __asm__ __volatile__( | ||
293 | " and %0, %5\n" | ||
294 | " mv r1, %1\n" | ||
295 | " beqz %0, strnlen_exit\n" | ||
296 | " and3 r0, %1, #3\n" | ||
297 | " bnez r0, strnlen_byte_loop\n" | ||
298 | " cmpui %0, #4\n" | ||
299 | " bc strnlen_byte_loop\n" | ||
300 | " sll3 r3, %6, #7\n" | ||
301 | "strnlen_word_loop:\n" | ||
302 | "0: ld r0, @%1+\n" | ||
303 | " not r2, r0\n" | ||
304 | " sub r0, %6\n" | ||
305 | " and r2, r3\n" | ||
306 | " and r2, r0\n" | ||
307 | " bnez r2, strnlen_last_bytes_fixup\n" | ||
308 | " addi %0, #-4\n" | ||
309 | " beqz %0, strnlen_exit\n" | ||
310 | " bgtz %0, strnlen_word_loop\n" | ||
311 | "strnlen_last_bytes:\n" | ||
312 | " mv %0, %4\n" | ||
313 | "strnlen_last_bytes_fixup:\n" | ||
314 | " addi %1, #-4\n" | ||
315 | "strnlen_byte_loop:\n" | ||
316 | "1: ldb r0, @%1\n" | ||
317 | " addi %0, #-1\n" | ||
318 | " beqz r0, strnlen_exit\n" | ||
319 | " addi %1, #1\n" | ||
320 | " bnez %0, strnlen_byte_loop\n" | ||
321 | "strnlen_exit:\n" | ||
322 | " sub %1, r1\n" | ||
323 | " add3 %0, %1, #1\n" | ||
324 | " .fillinsn\n" | ||
325 | "9:\n" | ||
326 | ".section .fixup,\"ax\"\n" | ||
327 | " .balign 4\n" | ||
328 | "4: addi %1, #-4\n" | ||
329 | " .fillinsn\n" | ||
330 | "5: ldi %0, #0\n" | ||
331 | " seth r1, #high(9b)\n" | ||
332 | " or3 r1, r1, #low(9b)\n" | ||
333 | " jmp r1\n" | ||
334 | ".previous\n" | ||
335 | ".section __ex_table,\"a\"\n" | ||
336 | " .balign 4\n" | ||
337 | " .long 0b,4b\n" | ||
338 | " .long 1b,5b\n" | ||
339 | ".previous" | ||
340 | : "=&r" (res), "=r" (s) | ||
341 | : "0" (n), "1" (s), "r" (n & 3), "r" (mask), "r"(0x01010101) | ||
342 | : "r0", "r1", "r2", "r3", "cbit"); | ||
343 | |||
344 | /* NOTE: strnlen_user() algorithm: | ||
345 | * { | ||
346 | * char *p; | ||
347 | * for (p = s; n-- && *p != '\0'; ++p) | ||
348 | * ; | ||
349 | * return p - s + 1; | ||
350 | * } | ||
351 | */ | ||
352 | |||
353 | /* NOTE: If a null char. exists, return 0. | ||
354 | * if ((x - 0x01010101) & ~x & 0x80808080)\n" | ||
355 | * return 0;\n" | ||
356 | */ | ||
357 | |||
358 | return res & mask; | ||
359 | } | ||
360 | |||
361 | #endif /* CONFIG_ISA_DUAL_ISSUE */ | ||
362 | |||