uaccess.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:16k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. #ifndef __i386_UACCESS_H
  2. #define __i386_UACCESS_H
  3. /*
  4.  * User space memory access functions
  5.  */
  6. #include <linux/config.h>
  7. #include <linux/sched.h>
  8. #include <linux/prefetch.h>
  9. #include <asm/page.h>
  10. #define VERIFY_READ 0
  11. #define VERIFY_WRITE 1
  12. /*
  13.  * The fs value determines whether argument validity checking should be
  14.  * performed or not.  If get_fs() == USER_DS, checking is performed, with
  15.  * get_fs() == KERNEL_DS, checking is bypassed.
  16.  *
  17.  * For historical reasons, these macros are grossly misnamed.
  18.  */
  19. #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
  20. #define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF)
  21. #define USER_DS MAKE_MM_SEG(PAGE_OFFSET)
  22. #define get_ds() (KERNEL_DS)
  23. #define get_fs() (current->addr_limit)
  24. #define set_fs(x) (current->addr_limit = (x))
  25. #define segment_eq(a,b) ((a).seg == (b).seg)
  26. extern int __verify_write(const void *, unsigned long);
  27. #define __addr_ok(addr) ((unsigned long)(addr) < (current->addr_limit.seg))
  28. /*
  29.  * Uhhuh, this needs 33-bit arithmetic. We have a carry..
  30.  */
  31. #define __range_ok(addr,size) ({ 
  32. unsigned long flag,sum; 
  33. asm("addl %3,%1 ; sbbl %0,%0; cmpl %1,%4; sbbl $0,%0" 
  34. :"=&r" (flag), "=r" (sum) 
  35. :"1" (addr),"g" ((int)(size)),"g" (current->addr_limit.seg)); 
  36. flag; })
  37. #ifdef CONFIG_X86_WP_WORKS_OK
  38. #define access_ok(type,addr,size) (__range_ok(addr,size) == 0)
  39. #else
  40. #define access_ok(type,addr,size) ( (__range_ok(addr,size) == 0) && 
  41.  ((type) == VERIFY_READ || boot_cpu_data.wp_works_ok || 
  42.  segment_eq(get_fs(),KERNEL_DS) || 
  43.   __verify_write((void *)(addr),(size))))
  44. #endif
  45. static inline int verify_area(int type, const void * addr, unsigned long size)
  46. {
  47. return access_ok(type,addr,size) ? 0 : -EFAULT;
  48. }
  49. /*
  50.  * The exception table consists of pairs of addresses: the first is the
  51.  * address of an instruction that is allowed to fault, and the second is
  52.  * the address at which the program should continue.  No registers are
  53.  * modified, so it is entirely up to the continuation code to figure out
  54.  * what to do.
  55.  *
  56.  * All the routines below use bits of fixup code that are out of line
  57.  * with the main instruction path.  This means when everything is well,
  58.  * we don't even have to jump over them.  Further, they do not intrude
  59.  * on our cache or tlb entries.
  60.  */
  61. struct exception_table_entry
  62. {
  63. unsigned long insn, fixup;
  64. };
  65. /* Returns 0 if exception not found and fixup otherwise.  */
  66. extern unsigned long search_exception_table(unsigned long);
  67. /*
  68.  * These are the main single-value transfer routines.  They automatically
  69.  * use the right size if we just have the right pointer type.
  70.  *
  71.  * This gets kind of ugly. We want to return _two_ values in "get_user()"
  72.  * and yet we don't want to do any pointers, because that is too much
  73.  * of a performance impact. Thus we have a few rather ugly macros here,
  74.  * and hide all the uglyness from the user.
  75.  *
  76.  * The "__xxx" versions of the user access functions are versions that
  77.  * do not verify the address space, that must have been done previously
  78.  * with a separate "access_ok()" call (this is used when we do multiple
  79.  * accesses to the same area of user memory).
  80.  */
  81. extern void __get_user_1(void);
  82. extern void __get_user_2(void);
  83. extern void __get_user_4(void);
  84. #define __get_user_x(size,ret,x,ptr) 
  85. __asm__ __volatile__("call __get_user_" #size 
  86. :"=a" (ret),"=d" (x) 
  87. :"0" (ptr))
  88. /* Careful: we have to cast the result to the type of the pointer for sign reasons */
  89. #define get_user(x,ptr)
  90. ({ int __ret_gu,__val_gu;
  91. switch(sizeof (*(ptr))) {
  92. case 1:  __get_user_x(1,__ret_gu,__val_gu,ptr); break;
  93. case 2:  __get_user_x(2,__ret_gu,__val_gu,ptr); break;
  94. case 4:  __get_user_x(4,__ret_gu,__val_gu,ptr); break;
  95. default: __get_user_x(X,__ret_gu,__val_gu,ptr); break;
  96. }
  97. (x) = (__typeof__(*(ptr)))__val_gu;
  98. __ret_gu;
  99. })
  100. extern void __put_user_1(void);
  101. extern void __put_user_2(void);
  102. extern void __put_user_4(void);
  103. extern void __put_user_8(void);
  104. extern void __put_user_bad(void);
  105. #define put_user(x,ptr)
  106.   __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
  107. #define __get_user(x,ptr) 
  108.   __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
  109. #define __put_user(x,ptr) 
  110.   __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
  111. #define __put_user_nocheck(x,ptr,size)
  112. ({
  113. long __pu_err;
  114. __put_user_size((x),(ptr),(size),__pu_err);
  115. __pu_err;
  116. })
  117. #define __put_user_check(x,ptr,size)
  118. ({
  119. long __pu_err = -EFAULT;
  120. __typeof__(*(ptr)) *__pu_addr = (ptr);
  121. if (access_ok(VERIFY_WRITE,__pu_addr,size))
  122. __put_user_size((x),__pu_addr,(size),__pu_err);
  123. __pu_err;
  124. })
  125. #define __put_user_u64(x, addr, err)
  126. __asm__ __volatile__(
  127. "1: movl %%eax,0(%2)n"
  128. "2: movl %%edx,4(%2)n"
  129. "3:n"
  130. ".section .fixup,"ax"n"
  131. "4: movl %3,%0n"
  132. " jmp 3bn"
  133. ".previousn"
  134. ".section __ex_table,"a"n"
  135. " .align 4n"
  136. " .long 1b,4bn"
  137. " .long 2b,4bn"
  138. ".previous"
  139. : "=r"(err)
  140. : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
  141. #define __put_user_size(x,ptr,size,retval)
  142. do {
  143. retval = 0;
  144. switch (size) {
  145.   case 1: __put_user_asm(x,ptr,retval,"b","b","iq"); break;
  146.   case 2: __put_user_asm(x,ptr,retval,"w","w","ir"); break;
  147.   case 4: __put_user_asm(x,ptr,retval,"l","","ir"); break;
  148.   case 8: __put_user_u64(x,ptr,retval); break;
  149.   default: __put_user_bad();
  150. }
  151. } while (0)
  152. struct __large_struct { unsigned long buf[100]; };
  153. #define __m(x) (*(struct __large_struct *)(x))
  154. /*
  155.  * Tell gcc we read from memory instead of writing: this is because
  156.  * we do not write to any memory gcc knows about, so there are no
  157.  * aliasing issues.
  158.  */
  159. #define __put_user_asm(x, addr, err, itype, rtype, ltype)
  160. __asm__ __volatile__(
  161. "1: mov"itype" %"rtype"1,%2n"
  162. "2:n"
  163. ".section .fixup,"ax"n"
  164. "3: movl %3,%0n"
  165. " jmp 2bn"
  166. ".previousn"
  167. ".section __ex_table,"a"n"
  168. " .align 4n"
  169. " .long 1b,3bn"
  170. ".previous"
  171. : "=r"(err)
  172. : ltype (x), "m"(__m(addr)), "i"(-EFAULT), "0"(err))
  173. #define __get_user_nocheck(x,ptr,size)
  174. ({
  175. long __gu_err, __gu_val;
  176. __get_user_size(__gu_val,(ptr),(size),__gu_err);
  177. (x) = (__typeof__(*(ptr)))__gu_val;
  178. __gu_err;
  179. })
  180. extern long __get_user_bad(void);
  181. #define __get_user_size(x,ptr,size,retval)
  182. do {
  183. retval = 0;
  184. switch (size) {
  185.   case 1: __get_user_asm(x,ptr,retval,"b","b","=q"); break;
  186.   case 2: __get_user_asm(x,ptr,retval,"w","w","=r"); break;
  187.   case 4: __get_user_asm(x,ptr,retval,"l","","=r"); break;
  188.   default: (x) = __get_user_bad();
  189. }
  190. } while (0)
  191. #define __get_user_asm(x, addr, err, itype, rtype, ltype)
  192. __asm__ __volatile__(
  193. "1: mov"itype" %2,%"rtype"1n"
  194. "2:n"
  195. ".section .fixup,"ax"n"
  196. "3: movl %3,%0n"
  197. " xor"itype" %"rtype"1,%"rtype"1n"
  198. " jmp 2bn"
  199. ".previousn"
  200. ".section __ex_table,"a"n"
  201. " .align 4n"
  202. " .long 1b,3bn"
  203. ".previous"
  204. : "=r"(err), ltype (x)
  205. : "m"(__m(addr)), "i"(-EFAULT), "0"(err))
  206. /*
  207.  * Copy To/From Userspace
  208.  */
  209. /* Generic arbitrary sized copy.  */
  210. #define __copy_user(to,from,size)
  211. do {
  212. int __d0, __d1;
  213. __asm__ __volatile__(
  214. "0: rep; movsln"
  215. " movl %3,%0n"
  216. "1: rep; movsbn"
  217. "2:n"
  218. ".section .fixup,"ax"n"
  219. "3: lea 0(%3,%0,4),%0n"
  220. " jmp 2bn"
  221. ".previousn"
  222. ".section __ex_table,"a"n"
  223. " .align 4n"
  224. " .long 0b,3bn"
  225. " .long 1b,2bn"
  226. ".previous"
  227. : "=&c"(size), "=&D" (__d0), "=&S" (__d1)
  228. : "r"(size & 3), "0"(size / 4), "1"(to), "2"(from)
  229. : "memory");
  230. } while (0)
  231. #define __copy_user_zeroing(to,from,size)
  232. do {
  233. int __d0, __d1;
  234. __asm__ __volatile__(
  235. "0: rep; movsln"
  236. " movl %3,%0n"
  237. "1: rep; movsbn"
  238. "2:n"
  239. ".section .fixup,"ax"n"
  240. "3: lea 0(%3,%0,4),%0n"
  241. "4: pushl %0n"
  242. " pushl %%eaxn"
  243. " xorl %%eax,%%eaxn"
  244. " rep; stosbn"
  245. " popl %%eaxn"
  246. " popl %0n"
  247. " jmp 2bn"
  248. ".previousn"
  249. ".section __ex_table,"a"n"
  250. " .align 4n"
  251. " .long 0b,3bn"
  252. " .long 1b,4bn"
  253. ".previous"
  254. : "=&c"(size), "=&D" (__d0), "=&S" (__d1)
  255. : "r"(size & 3), "0"(size / 4), "1"(to), "2"(from)
  256. : "memory");
  257. } while (0)
  258. /* We let the __ versions of copy_from/to_user inline, because they're often
  259.  * used in fast paths and have only a small space overhead.
  260.  */
  261. static inline unsigned long
  262. __generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
  263. {
  264. __copy_user_zeroing(to,from,n);
  265. return n;
  266. }
  267. static inline unsigned long
  268. __generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
  269. {
  270. __copy_user(to,from,n);
  271. return n;
  272. }
  273. /* Optimize just a little bit when we know the size of the move. */
  274. #define __constant_copy_user(to, from, size)
  275. do {
  276. int __d0, __d1;
  277. switch (size & 3) {
  278. default:
  279. __asm__ __volatile__(
  280. "0: rep; movsln"
  281. "1:n"
  282. ".section .fixup,"ax"n"
  283. "2: shl $2,%0n"
  284. " jmp 1bn"
  285. ".previousn"
  286. ".section __ex_table,"a"n"
  287. " .align 4n"
  288. " .long 0b,2bn"
  289. ".previous"
  290. : "=c"(size), "=&S" (__d0), "=&D" (__d1)
  291. : "1"(from), "2"(to), "0"(size/4)
  292. : "memory");
  293. break;
  294. case 1:
  295. __asm__ __volatile__(
  296. "0: rep; movsln"
  297. "1: movsbn"
  298. "2:n"
  299. ".section .fixup,"ax"n"
  300. "3: shl $2,%0n"
  301. "4: incl %0n"
  302. " jmp 2bn"
  303. ".previousn"
  304. ".section __ex_table,"a"n"
  305. " .align 4n"
  306. " .long 0b,3bn"
  307. " .long 1b,4bn"
  308. ".previous"
  309. : "=c"(size), "=&S" (__d0), "=&D" (__d1)
  310. : "1"(from), "2"(to), "0"(size/4)
  311. : "memory");
  312. break;
  313. case 2:
  314. __asm__ __volatile__(
  315. "0: rep; movsln"
  316. "1: movswn"
  317. "2:n"
  318. ".section .fixup,"ax"n"
  319. "3: shl $2,%0n"
  320. "4: addl $2,%0n"
  321. " jmp 2bn"
  322. ".previousn"
  323. ".section __ex_table,"a"n"
  324. " .align 4n"
  325. " .long 0b,3bn"
  326. " .long 1b,4bn"
  327. ".previous"
  328. : "=c"(size), "=&S" (__d0), "=&D" (__d1)
  329. : "1"(from), "2"(to), "0"(size/4)
  330. : "memory");
  331. break;
  332. case 3:
  333. __asm__ __volatile__(
  334. "0: rep; movsln"
  335. "1: movswn"
  336. "2: movsbn"
  337. "3:n"
  338. ".section .fixup,"ax"n"
  339. "4: shl $2,%0n"
  340. "5: addl $2,%0n"
  341. "6: incl %0n"
  342. " jmp 3bn"
  343. ".previousn"
  344. ".section __ex_table,"a"n"
  345. " .align 4n"
  346. " .long 0b,4bn"
  347. " .long 1b,5bn"
  348. " .long 2b,6bn"
  349. ".previous"
  350. : "=c"(size), "=&S" (__d0), "=&D" (__d1)
  351. : "1"(from), "2"(to), "0"(size/4)
  352. : "memory");
  353. break;
  354. }
  355. } while (0)
  356. /* Optimize just a little bit when we know the size of the move. */
  357. #define __constant_copy_user_zeroing(to, from, size)
  358. do {
  359. int __d0, __d1;
  360. switch (size & 3) {
  361. default:
  362. __asm__ __volatile__(
  363. "0: rep; movsln"
  364. "1:n"
  365. ".section .fixup,"ax"n"
  366. "2: pushl %0n"
  367. " pushl %%eaxn"
  368. " xorl %%eax,%%eaxn"
  369. " rep; stosln"
  370. " popl %%eaxn"
  371. " popl %0n"
  372. " shl $2,%0n"
  373. " jmp 1bn"
  374. ".previousn"
  375. ".section __ex_table,"a"n"
  376. " .align 4n"
  377. " .long 0b,2bn"
  378. ".previous"
  379. : "=c"(size), "=&S" (__d0), "=&D" (__d1)
  380. : "1"(from), "2"(to), "0"(size/4)
  381. : "memory");
  382. break;
  383. case 1:
  384. __asm__ __volatile__(
  385. "0: rep; movsln"
  386. "1: movsbn"
  387. "2:n"
  388. ".section .fixup,"ax"n"
  389. "3: pushl %0n"
  390. " pushl %%eaxn"
  391. " xorl %%eax,%%eaxn"
  392. " rep; stosln"
  393. " stosbn"
  394. " popl %%eaxn"
  395. " popl %0n"
  396. " shl $2,%0n"
  397. " incl %0n"
  398. " jmp 2bn"
  399. "4: pushl %%eaxn"
  400. " xorl %%eax,%%eaxn"
  401. " stosbn"
  402. " popl %%eaxn"
  403. " incl %0n"
  404. " jmp 2bn"
  405. ".previousn"
  406. ".section __ex_table,"a"n"
  407. " .align 4n"
  408. " .long 0b,3bn"
  409. " .long 1b,4bn"
  410. ".previous"
  411. : "=c"(size), "=&S" (__d0), "=&D" (__d1)
  412. : "1"(from), "2"(to), "0"(size/4)
  413. : "memory");
  414. break;
  415. case 2:
  416. __asm__ __volatile__(
  417. "0: rep; movsln"
  418. "1: movswn"
  419. "2:n"
  420. ".section .fixup,"ax"n"
  421. "3: pushl %0n"
  422. " pushl %%eaxn"
  423. " xorl %%eax,%%eaxn"
  424. " rep; stosln"
  425. " stoswn"
  426. " popl %%eaxn"
  427. " popl %0n"
  428. " shl $2,%0n"
  429. " addl $2,%0n"
  430. " jmp 2bn"
  431. "4: pushl %%eaxn"
  432. " xorl %%eax,%%eaxn"
  433. " stoswn"
  434. " popl %%eaxn"
  435. " addl $2,%0n"
  436. " jmp 2bn"
  437. ".previousn"
  438. ".section __ex_table,"a"n"
  439. " .align 4n"
  440. " .long 0b,3bn"
  441. " .long 1b,4bn"
  442. ".previous"
  443. : "=c"(size), "=&S" (__d0), "=&D" (__d1)
  444. : "1"(from), "2"(to), "0"(size/4)
  445. : "memory");
  446. break;
  447. case 3:
  448. __asm__ __volatile__(
  449. "0: rep; movsln"
  450. "1: movswn"
  451. "2: movsbn"
  452. "3:n"
  453. ".section .fixup,"ax"n"
  454. "4: pushl %0n"
  455. " pushl %%eaxn"
  456. " xorl %%eax,%%eaxn"
  457. " rep; stosln"
  458. " stoswn"
  459. " stosbn"
  460. " popl %%eaxn"
  461. " popl %0n"
  462. " shl $2,%0n"
  463. " addl $3,%0n"
  464. " jmp 2bn"
  465. "5: pushl %%eaxn"
  466. " xorl %%eax,%%eaxn"
  467. " stoswn"
  468. " stosbn"
  469. " popl %%eaxn"
  470. " addl $3,%0n"
  471. " jmp 2bn"
  472. "6: pushl %%eaxn"
  473. " xorl %%eax,%%eaxn"
  474. " stosbn"
  475. " popl %%eaxn"
  476. " incl %0n"
  477. " jmp 3bn"
  478. ".previousn"
  479. ".section __ex_table,"a"n"
  480. " .align 4n"
  481. " .long 0b,4bn"
  482. " .long 1b,5bn"
  483. " .long 2b,6bn"
  484. ".previous"
  485. : "=c"(size), "=&S" (__d0), "=&D" (__d1)
  486. : "1"(from), "2"(to), "0"(size/4)
  487. : "memory");
  488. break;
  489. }
  490. } while (0)
  491. unsigned long __generic_copy_to_user(void *, const void *, unsigned long);
  492. unsigned long __generic_copy_from_user(void *, const void *, unsigned long);
  493. static inline unsigned long
  494. __constant_copy_to_user(void *to, const void *from, unsigned long n)
  495. {
  496. prefetch(from);
  497. if (access_ok(VERIFY_WRITE, to, n))
  498. __constant_copy_user(to,from,n);
  499. return n;
  500. }
  501. static inline unsigned long
  502. __constant_copy_from_user(void *to, const void *from, unsigned long n)
  503. {
  504. if (access_ok(VERIFY_READ, from, n))
  505. __constant_copy_user_zeroing(to,from,n);
  506. else
  507. memset(to, 0, n);
  508. return n;
  509. }
  510. static inline unsigned long
  511. __constant_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
  512. {
  513. __constant_copy_user(to,from,n);
  514. return n;
  515. }
  516. static inline unsigned long
  517. __constant_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
  518. {
  519. __constant_copy_user_zeroing(to,from,n);
  520. return n;
  521. }
  522. #define copy_to_user(to,from,n)
  523. (__builtin_constant_p(n) ?
  524.  __constant_copy_to_user((to),(from),(n)) :
  525.  __generic_copy_to_user((to),(from),(n)))
  526. #define copy_from_user(to,from,n)
  527. (__builtin_constant_p(n) ?
  528.  __constant_copy_from_user((to),(from),(n)) :
  529.  __generic_copy_from_user((to),(from),(n)))
  530. #define __copy_to_user(to,from,n)
  531. (__builtin_constant_p(n) ?
  532.  __constant_copy_to_user_nocheck((to),(from),(n)) :
  533.  __generic_copy_to_user_nocheck((to),(from),(n)))
  534. #define __copy_from_user(to,from,n)
  535. (__builtin_constant_p(n) ?
  536.  __constant_copy_from_user_nocheck((to),(from),(n)) :
  537.  __generic_copy_from_user_nocheck((to),(from),(n)))
  538. long strncpy_from_user(char *dst, const char *src, long count);
  539. long __strncpy_from_user(char *dst, const char *src, long count);
  540. #define strlen_user(str) strnlen_user(str, ~0UL >> 1)
  541. long strnlen_user(const char *str, long n);
  542. unsigned long clear_user(void *mem, unsigned long len);
  543. unsigned long __clear_user(void *mem, unsigned long len);
  544. #endif /* __i386_UACCESS_H */