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 --- |