uaccess.h (9f73bd8bb445e0cbe4bcef6d4cfc788f1e184007) uaccess.h (dfd45b6103c973bfcea2341d89e36faf947dbc33)
1/*
2 * arch/arm/include/asm/uaccess.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#ifndef _ASMARM_UACCESS_H

--- 90 unchanged lines hidden (view full) ---

99static inline void set_fs(mm_segment_t fs)
100{
101 current_thread_info()->addr_limit = fs;
102 modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);
103}
104
105#define segment_eq(a, b) ((a) == (b))
106
1/*
2 * arch/arm/include/asm/uaccess.h
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#ifndef _ASMARM_UACCESS_H

--- 90 unchanged lines hidden (view full) ---

99static inline void set_fs(mm_segment_t fs)
100{
101 current_thread_info()->addr_limit = fs;
102 modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);
103}
104
105#define segment_eq(a, b) ((a) == (b))
106
107#define __addr_ok(addr) ({ \
108 unsigned long flag; \
109 __asm__("cmp %2, %0; movlo %0, #0" \
110 : "=&r" (flag) \
111 : "0" (current_thread_info()->addr_limit), "r" (addr) \
112 : "cc"); \
113 (flag == 0); })
114
107/* We use 33-bit arithmetic here... */
108#define __range_ok(addr, size) ({ \
109 unsigned long flag, roksum; \
110 __chk_user_ptr(addr); \
111 __asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \
112 : "=&r" (flag), "=&r" (roksum) \
113 : "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \
114 : "cc"); \

--- 110 unchanged lines hidden (view full) ---

225 __get_user_check(x, p); \
226 })
227
228extern int __put_user_1(void *, unsigned int);
229extern int __put_user_2(void *, unsigned int);
230extern int __put_user_4(void *, unsigned int);
231extern int __put_user_8(void *, unsigned long long);
232
115/* We use 33-bit arithmetic here... */
116#define __range_ok(addr, size) ({ \
117 unsigned long flag, roksum; \
118 __chk_user_ptr(addr); \
119 __asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \
120 : "=&r" (flag), "=&r" (roksum) \
121 : "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \
122 : "cc"); \

--- 110 unchanged lines hidden (view full) ---

233 __get_user_check(x, p); \
234 })
235
236extern int __put_user_1(void *, unsigned int);
237extern int __put_user_2(void *, unsigned int);
238extern int __put_user_4(void *, unsigned int);
239extern int __put_user_8(void *, unsigned long long);
240
233#define __put_user_check(__pu_val, __ptr, __err, __s) \
241#define __put_user_x(__r2, __p, __e, __l, __s) \
242 __asm__ __volatile__ ( \
243 __asmeq("%0", "r0") __asmeq("%2", "r2") \
244 __asmeq("%3", "r1") \
245 "bl __put_user_" #__s \
246 : "=&r" (__e) \
247 : "0" (__p), "r" (__r2), "r" (__l) \
248 : "ip", "lr", "cc")
249
250#define __put_user_check(x, p) \
234 ({ \
235 unsigned long __limit = current_thread_info()->addr_limit - 1; \
251 ({ \
252 unsigned long __limit = current_thread_info()->addr_limit - 1; \
236 register typeof(__pu_val) __r2 asm("r2") = __pu_val; \
237 register const void __user *__p asm("r0") = __ptr; \
253 const typeof(*(p)) __user *__tmp_p = (p); \
254 register const typeof(*(p)) __r2 asm("r2") = (x); \
255 register const typeof(*(p)) __user *__p asm("r0") = __tmp_p; \
238 register unsigned long __l asm("r1") = __limit; \
239 register int __e asm("r0"); \
256 register unsigned long __l asm("r1") = __limit; \
257 register int __e asm("r0"); \
240 __asm__ __volatile__ ( \
241 __asmeq("%0", "r0") __asmeq("%2", "r2") \
242 __asmeq("%3", "r1") \
243 "bl __put_user_" #__s \
244 : "=&r" (__e) \
245 : "0" (__p), "r" (__r2), "r" (__l) \
246 : "ip", "lr", "cc"); \
247 __err = __e; \
258 unsigned int __ua_flags = uaccess_save_and_enable(); \
259 switch (sizeof(*(__p))) { \
260 case 1: \
261 __put_user_x(__r2, __p, __e, __l, 1); \
262 break; \
263 case 2: \
264 __put_user_x(__r2, __p, __e, __l, 2); \
265 break; \
266 case 4: \
267 __put_user_x(__r2, __p, __e, __l, 4); \
268 break; \
269 case 8: \
270 __put_user_x(__r2, __p, __e, __l, 8); \
271 break; \
272 default: __e = __put_user_bad(); break; \
273 } \
274 uaccess_restore(__ua_flags); \
275 __e; \
248 })
249
276 })
277
278#define put_user(x, p) \
279 ({ \
280 might_fault(); \
281 __put_user_check(x, p); \
282 })
283
250#else /* CONFIG_MMU */
251
252/*
253 * uClinux has only one addr space, so has simplified address limits.
254 */
255#define USER_DS KERNEL_DS
256
257#define segment_eq(a, b) (1)
258#define __addr_ok(addr) ((void)(addr), 1)
259#define __range_ok(addr, size) ((void)(addr), 0)
260#define get_fs() (KERNEL_DS)
261
262static inline void set_fs(mm_segment_t fs)
263{
264}
265
266#define get_user(x, p) __get_user(x, p)
284#else /* CONFIG_MMU */
285
286/*
287 * uClinux has only one addr space, so has simplified address limits.
288 */
289#define USER_DS KERNEL_DS
290
291#define segment_eq(a, b) (1)
292#define __addr_ok(addr) ((void)(addr), 1)
293#define __range_ok(addr, size) ((void)(addr), 0)
294#define get_fs() (KERNEL_DS)
295
296static inline void set_fs(mm_segment_t fs)
297{
298}
299
300#define get_user(x, p) __get_user(x, p)
267#define __put_user_check __put_user_nocheck
301#define put_user(x, p) __put_user(x, p)
268
269#endif /* CONFIG_MMU */
270
271#define access_ok(type, addr, size) (__range_ok(addr, size) == 0)
272
273#define user_addr_max() \
274 (segment_eq(get_fs(), KERNEL_DS) ? ~0UL : get_fs())
275

--- 74 unchanged lines hidden (view full) ---

350 __get_user_asm_byte(__b2, __gu_addr + 1, err); \
351 (x) = (__b1 << 8) | __b2; \
352})
353#endif
354
355#define __get_user_asm_word(x, addr, err) \
356 __get_user_asm(x, addr, err, ldr)
357
302
303#endif /* CONFIG_MMU */
304
305#define access_ok(type, addr, size) (__range_ok(addr, size) == 0)
306
307#define user_addr_max() \
308 (segment_eq(get_fs(), KERNEL_DS) ? ~0UL : get_fs())
309

--- 74 unchanged lines hidden (view full) ---

384 __get_user_asm_byte(__b2, __gu_addr + 1, err); \
385 (x) = (__b1 << 8) | __b2; \
386})
387#endif
388
389#define __get_user_asm_word(x, addr, err) \
390 __get_user_asm(x, addr, err, ldr)
391
358
359#define __put_user_switch(x, ptr, __err, __fn) \
360 do { \
361 const __typeof__(*(ptr)) __user *__pu_ptr = (ptr); \
362 __typeof__(*(ptr)) __pu_val = (x); \
363 unsigned int __ua_flags; \
364 might_fault(); \
365 __ua_flags = uaccess_save_and_enable(); \
366 switch (sizeof(*(ptr))) { \
367 case 1: __fn(__pu_val, __pu_ptr, __err, 1); break; \
368 case 2: __fn(__pu_val, __pu_ptr, __err, 2); break; \
369 case 4: __fn(__pu_val, __pu_ptr, __err, 4); break; \
370 case 8: __fn(__pu_val, __pu_ptr, __err, 8); break; \
371 default: __err = __put_user_bad(); break; \
372 } \
373 uaccess_restore(__ua_flags); \
374 } while (0)
375
376#define put_user(x, ptr) \
377({ \
378 int __pu_err = 0; \
379 __put_user_switch((x), (ptr), __pu_err, __put_user_check); \
380 __pu_err; \
381})
382
383#define __put_user(x, ptr) \
384({ \
385 long __pu_err = 0; \
392#define __put_user(x, ptr) \
393({ \
394 long __pu_err = 0; \
386 __put_user_switch((x), (ptr), __pu_err, __put_user_nocheck); \
395 __put_user_err((x), (ptr), __pu_err); \
387 __pu_err; \
388})
389
390#define __put_user_error(x, ptr, err) \
391({ \
396 __pu_err; \
397})
398
399#define __put_user_error(x, ptr, err) \
400({ \
392 __put_user_switch((x), (ptr), (err), __put_user_nocheck); \
401 __put_user_err((x), (ptr), err); \
393 (void) 0; \
394})
395
402 (void) 0; \
403})
404
396#define __put_user_nocheck(x, __pu_ptr, __err, __size) \
397 do { \
398 unsigned long __pu_addr = (unsigned long)__pu_ptr; \
399 __put_user_nocheck_##__size(x, __pu_addr, __err); \
400 } while (0)
405#define __put_user_err(x, ptr, err) \
406do { \
407 unsigned long __pu_addr = (unsigned long)(ptr); \
408 unsigned int __ua_flags; \
409 __typeof__(*(ptr)) __pu_val = (x); \
410 __chk_user_ptr(ptr); \
411 might_fault(); \
412 __ua_flags = uaccess_save_and_enable(); \
413 switch (sizeof(*(ptr))) { \
414 case 1: __put_user_asm_byte(__pu_val, __pu_addr, err); break; \
415 case 2: __put_user_asm_half(__pu_val, __pu_addr, err); break; \
416 case 4: __put_user_asm_word(__pu_val, __pu_addr, err); break; \
417 case 8: __put_user_asm_dword(__pu_val, __pu_addr, err); break; \
418 default: __put_user_bad(); \
419 } \
420 uaccess_restore(__ua_flags); \
421} while (0)
401
422
402#define __put_user_nocheck_1 __put_user_asm_byte
403#define __put_user_nocheck_2 __put_user_asm_half
404#define __put_user_nocheck_4 __put_user_asm_word
405#define __put_user_nocheck_8 __put_user_asm_dword
406
407#define __put_user_asm(x, __pu_addr, err, instr) \
408 __asm__ __volatile__( \
409 "1: " TUSER(instr) " %1, [%2], #0\n" \
410 "2:\n" \
411 " .pushsection .text.fixup,\"ax\"\n" \
412 " .align 2\n" \
413 "3: mov %0, %3\n" \
414 " b 2b\n" \

--- 60 unchanged lines hidden (view full) ---

475
476#ifdef CONFIG_MMU
477extern unsigned long __must_check
478arm_copy_from_user(void *to, const void __user *from, unsigned long n);
479
480static inline unsigned long __must_check
481__copy_from_user(void *to, const void __user *from, unsigned long n)
482{
423#define __put_user_asm(x, __pu_addr, err, instr) \
424 __asm__ __volatile__( \
425 "1: " TUSER(instr) " %1, [%2], #0\n" \
426 "2:\n" \
427 " .pushsection .text.fixup,\"ax\"\n" \
428 " .align 2\n" \
429 "3: mov %0, %3\n" \
430 " b 2b\n" \

--- 60 unchanged lines hidden (view full) ---

491
492#ifdef CONFIG_MMU
493extern unsigned long __must_check
494arm_copy_from_user(void *to, const void __user *from, unsigned long n);
495
496static inline unsigned long __must_check
497__copy_from_user(void *to, const void __user *from, unsigned long n)
498{
483 unsigned int __ua_flags = uaccess_save_and_enable();
499 unsigned int __ua_flags;
500
501 check_object_size(to, n, false);
502 __ua_flags = uaccess_save_and_enable();
484 n = arm_copy_from_user(to, from, n);
485 uaccess_restore(__ua_flags);
486 return n;
487}
488
489extern unsigned long __must_check
490arm_copy_to_user(void __user *to, const void *from, unsigned long n);
491extern unsigned long __must_check
492__copy_to_user_std(void __user *to, const void *from, unsigned long n);
493
494static inline unsigned long __must_check
495__copy_to_user(void __user *to, const void *from, unsigned long n)
496{
497#ifndef CONFIG_UACCESS_WITH_MEMCPY
503 n = arm_copy_from_user(to, from, n);
504 uaccess_restore(__ua_flags);
505 return n;
506}
507
508extern unsigned long __must_check
509arm_copy_to_user(void __user *to, const void *from, unsigned long n);
510extern unsigned long __must_check
511__copy_to_user_std(void __user *to, const void *from, unsigned long n);
512
513static inline unsigned long __must_check
514__copy_to_user(void __user *to, const void *from, unsigned long n)
515{
516#ifndef CONFIG_UACCESS_WITH_MEMCPY
498 unsigned int __ua_flags = uaccess_save_and_enable();
517 unsigned int __ua_flags;
518
519 check_object_size(from, n, true);
520 __ua_flags = uaccess_save_and_enable();
499 n = arm_copy_to_user(to, from, n);
500 uaccess_restore(__ua_flags);
501 return n;
502#else
521 n = arm_copy_to_user(to, from, n);
522 uaccess_restore(__ua_flags);
523 return n;
524#else
525 check_object_size(from, n, true);
503 return arm_copy_to_user(to, from, n);
504#endif
505}
506
507extern unsigned long __must_check
508arm_clear_user(void __user *addr, unsigned long n);
509extern unsigned long __must_check
510__clear_user_std(void __user *addr, unsigned long n);

--- 49 unchanged lines hidden ---
526 return arm_copy_to_user(to, from, n);
527#endif
528}
529
530extern unsigned long __must_check
531arm_clear_user(void __user *addr, unsigned long n);
532extern unsigned long __must_check
533__clear_user_std(void __user *addr, unsigned long n);

--- 49 unchanged lines hidden ---