home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / arch / cris / include / asm / uaccess.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  11.3 KB  |  405 lines

  1. /* 
  2.  * Authors:    Bjorn Wesen (bjornw@axis.com)
  3.  *           Hans-Peter Nilsson (hp@axis.com)
  4.  */
  5.  
  6. /* Asm:s have been tweaked (within the domain of correctness) to give
  7.    satisfactory results for "gcc version 2.96 20000427 (experimental)".
  8.  
  9.    Check regularly...
  10.  
  11.    Register $r9 is chosen for temporaries, being a call-clobbered register
  12.    first in line to be used (notably for local blocks), not colliding with
  13.    parameter registers.  */
  14.  
  15. #ifndef _CRIS_UACCESS_H
  16. #define _CRIS_UACCESS_H
  17.  
  18. #ifndef __ASSEMBLY__
  19. #include <linux/sched.h>
  20. #include <linux/errno.h>
  21. #include <asm/processor.h>
  22. #include <asm/page.h>
  23.  
  24. #define VERIFY_READ    0
  25. #define VERIFY_WRITE    1
  26.  
  27. /*
  28.  * The fs value determines whether argument validity checking should be
  29.  * performed or not.  If get_fs() == USER_DS, checking is performed, with
  30.  * get_fs() == KERNEL_DS, checking is bypassed.
  31.  *
  32.  * For historical reasons, these macros are grossly misnamed.
  33.  */
  34.  
  35. #define MAKE_MM_SEG(s)    ((mm_segment_t) { (s) })
  36.  
  37. /* addr_limit is the maximum accessible address for the task. we misuse
  38.  * the KERNEL_DS and USER_DS values to both assign and compare the 
  39.  * addr_limit values through the equally misnamed get/set_fs macros.
  40.  * (see above)
  41.  */
  42.  
  43. #define KERNEL_DS    MAKE_MM_SEG(0xFFFFFFFF)
  44. #define USER_DS        MAKE_MM_SEG(TASK_SIZE)
  45.  
  46. #define get_ds()    (KERNEL_DS)
  47. #define get_fs()    (current_thread_info()->addr_limit)
  48. #define set_fs(x)    (current_thread_info()->addr_limit = (x))
  49.  
  50. #define segment_eq(a,b)    ((a).seg == (b).seg)
  51.  
  52. #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
  53. #define __user_ok(addr,size) (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size)))
  54. #define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size)))
  55. #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size))
  56.  
  57. #include <arch/uaccess.h>
  58.  
  59. /*
  60.  * The exception table consists of pairs of addresses: the first is the
  61.  * address of an instruction that is allowed to fault, and the second is
  62.  * the address at which the program should continue.  No registers are
  63.  * modified, so it is entirely up to the continuation code to figure out
  64.  * what to do.
  65.  *
  66.  * All the routines below use bits of fixup code that are out of line
  67.  * with the main instruction path.  This means when everything is well,
  68.  * we don't even have to jump over them.  Further, they do not intrude
  69.  * on our cache or tlb entries.
  70.  */
  71.  
  72. struct exception_table_entry
  73. {
  74.     unsigned long insn, fixup;
  75. };
  76.  
  77. /*
  78.  * These are the main single-value transfer routines.  They automatically
  79.  * use the right size if we just have the right pointer type.
  80.  *
  81.  * This gets kind of ugly. We want to return _two_ values in "get_user()"
  82.  * and yet we don't want to do any pointers, because that is too much
  83.  * of a performance impact. Thus we have a few rather ugly macros here,
  84.  * and hide all the ugliness from the user.
  85.  *
  86.  * The "__xxx" versions of the user access functions are versions that
  87.  * do not verify the address space, that must have been done previously
  88.  * with a separate "access_ok()" call (this is used when we do multiple
  89.  * accesses to the same area of user memory).
  90.  *
  91.  * As we use the same address space for kernel and user data on
  92.  * CRIS, we can just do these as direct assignments.  (Of course, the
  93.  * exception handling means that it's no longer "just"...)
  94.  */
  95. #define get_user(x,ptr) \
  96.   __get_user_check((x),(ptr),sizeof(*(ptr)))
  97. #define put_user(x,ptr) \
  98.   __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
  99.  
  100. #define __get_user(x,ptr) \
  101.   __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
  102. #define __put_user(x,ptr) \
  103.   __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
  104.  
  105. extern long __put_user_bad(void);
  106.  
  107. #define __put_user_size(x,ptr,size,retval)            \
  108. do {                                \
  109.     retval = 0;                        \
  110.     switch (size) {                        \
  111.       case 1: __put_user_asm(x,ptr,retval,"move.b"); break;    \
  112.       case 2: __put_user_asm(x,ptr,retval,"move.w"); break;    \
  113.       case 4: __put_user_asm(x,ptr,retval,"move.d"); break;    \
  114.       case 8: __put_user_asm_64(x,ptr,retval); break;    \
  115.       default: __put_user_bad();                \
  116.     }                            \
  117. } while (0)
  118.  
  119. #define __get_user_size(x,ptr,size,retval)            \
  120. do {                                \
  121.     retval = 0;                        \
  122.     switch (size) {                        \
  123.       case 1: __get_user_asm(x,ptr,retval,"move.b"); break;    \
  124.       case 2: __get_user_asm(x,ptr,retval,"move.w"); break;    \
  125.       case 4: __get_user_asm(x,ptr,retval,"move.d"); break;    \
  126.       case 8: __get_user_asm_64(x,ptr,retval); break;    \
  127.       default: (x) = __get_user_bad();            \
  128.     }                            \
  129. } while (0)
  130.  
  131. #define __put_user_nocheck(x,ptr,size)            \
  132. ({                            \
  133.     long __pu_err;                    \
  134.     __put_user_size((x),(ptr),(size),__pu_err);    \
  135.     __pu_err;                    \
  136. })
  137.  
  138. #define __put_user_check(x,ptr,size)                \
  139. ({                                \
  140.     long __pu_err = -EFAULT;                \
  141.     __typeof__(*(ptr)) *__pu_addr = (ptr);            \
  142.     if (access_ok(VERIFY_WRITE,__pu_addr,size))        \
  143.         __put_user_size((x),__pu_addr,(size),__pu_err);    \
  144.     __pu_err;                        \
  145. })
  146.  
  147. struct __large_struct { unsigned long buf[100]; };
  148. #define __m(x) (*(struct __large_struct *)(x))
  149.  
  150.  
  151.  
  152. #define __get_user_nocheck(x,ptr,size)                \
  153. ({                                \
  154.     long __gu_err, __gu_val;                \
  155.     __get_user_size(__gu_val,(ptr),(size),__gu_err);    \
  156.     (x) = (__typeof__(*(ptr)))__gu_val;            \
  157.     __gu_err;                        \
  158. })
  159.  
  160. #define __get_user_check(x,ptr,size)                    \
  161. ({                                    \
  162.     long __gu_err = -EFAULT, __gu_val = 0;                \
  163.     const __typeof__(*(ptr)) *__gu_addr = (ptr);            \
  164.     if (access_ok(VERIFY_READ,__gu_addr,size))            \
  165.         __get_user_size(__gu_val,__gu_addr,(size),__gu_err);    \
  166.     (x) = (__typeof__(*(ptr)))__gu_val;                \
  167.     __gu_err;                            \
  168. })
  169.  
  170. extern long __get_user_bad(void);
  171.  
  172. /* More complex functions.  Most are inline, but some call functions that
  173.    live in lib/usercopy.c  */
  174.  
  175. extern unsigned long __copy_user(void __user *to, const void *from, unsigned long n);
  176. extern unsigned long __copy_user_zeroing(void *to, const void __user *from, unsigned long n);
  177. extern unsigned long __do_clear_user(void __user *to, unsigned long n);
  178.  
  179. static inline unsigned long
  180. __generic_copy_to_user(void __user *to, const void *from, unsigned long n)
  181. {
  182.     if (access_ok(VERIFY_WRITE, to, n))
  183.         return __copy_user(to,from,n);
  184.     return n;
  185. }
  186.  
  187. static inline unsigned long
  188. __generic_copy_from_user(void *to, const void __user *from, unsigned long n)
  189. {
  190.     if (access_ok(VERIFY_READ, from, n))
  191.         return __copy_user_zeroing(to,from,n);
  192.     return n;
  193. }
  194.  
  195. static inline unsigned long
  196. __generic_clear_user(void __user *to, unsigned long n)
  197. {
  198.     if (access_ok(VERIFY_WRITE, to, n))
  199.         return __do_clear_user(to,n);
  200.     return n;
  201. }
  202.  
  203. static inline long
  204. __strncpy_from_user(char *dst, const char __user *src, long count)
  205. {
  206.     return __do_strncpy_from_user(dst, src, count);
  207. }
  208.  
  209. static inline long
  210. strncpy_from_user(char *dst, const char __user *src, long count)
  211. {
  212.     long res = -EFAULT;
  213.     if (access_ok(VERIFY_READ, src, 1))
  214.         res = __do_strncpy_from_user(dst, src, count);
  215.     return res;
  216. }
  217.  
  218.  
  219. /* Note that these expand awfully if made into switch constructs, so
  220.    don't do that.  */
  221.  
  222. static inline unsigned long
  223. __constant_copy_from_user(void *to, const void __user *from, unsigned long n)
  224. {
  225.     unsigned long ret = 0;
  226.     if (n == 0)
  227.         ;
  228.     else if (n == 1)
  229.         __asm_copy_from_user_1(to, from, ret);
  230.     else if (n == 2)
  231.         __asm_copy_from_user_2(to, from, ret);
  232.     else if (n == 3)
  233.         __asm_copy_from_user_3(to, from, ret);
  234.     else if (n == 4)
  235.         __asm_copy_from_user_4(to, from, ret);
  236.     else if (n == 5)
  237.         __asm_copy_from_user_5(to, from, ret);
  238.     else if (n == 6)
  239.         __asm_copy_from_user_6(to, from, ret);
  240.     else if (n == 7)
  241.         __asm_copy_from_user_7(to, from, ret);
  242.     else if (n == 8)
  243.         __asm_copy_from_user_8(to, from, ret);
  244.     else if (n == 9)
  245.         __asm_copy_from_user_9(to, from, ret);
  246.     else if (n == 10)
  247.         __asm_copy_from_user_10(to, from, ret);
  248.     else if (n == 11)
  249.         __asm_copy_from_user_11(to, from, ret);
  250.     else if (n == 12)
  251.         __asm_copy_from_user_12(to, from, ret);
  252.     else if (n == 13)
  253.         __asm_copy_from_user_13(to, from, ret);
  254.     else if (n == 14)
  255.         __asm_copy_from_user_14(to, from, ret);
  256.     else if (n == 15)
  257.         __asm_copy_from_user_15(to, from, ret);
  258.     else if (n == 16)
  259.         __asm_copy_from_user_16(to, from, ret);
  260.     else if (n == 20)
  261.         __asm_copy_from_user_20(to, from, ret);
  262.     else if (n == 24)
  263.         __asm_copy_from_user_24(to, from, ret);
  264.     else
  265.         ret = __generic_copy_from_user(to, from, n);
  266.  
  267.     return ret;
  268. }
  269.  
  270. /* Ditto, don't make a switch out of this.  */
  271.  
  272. static inline unsigned long
  273. __constant_copy_to_user(void __user *to, const void *from, unsigned long n)
  274. {
  275.     unsigned long ret = 0;
  276.     if (n == 0)
  277.         ;
  278.     else if (n == 1)
  279.         __asm_copy_to_user_1(to, from, ret);
  280.     else if (n == 2)
  281.         __asm_copy_to_user_2(to, from, ret);
  282.     else if (n == 3)
  283.         __asm_copy_to_user_3(to, from, ret);
  284.     else if (n == 4)
  285.         __asm_copy_to_user_4(to, from, ret);
  286.     else if (n == 5)
  287.         __asm_copy_to_user_5(to, from, ret);
  288.     else if (n == 6)
  289.         __asm_copy_to_user_6(to, from, ret);
  290.     else if (n == 7)
  291.         __asm_copy_to_user_7(to, from, ret);
  292.     else if (n == 8)
  293.         __asm_copy_to_user_8(to, from, ret);
  294.     else if (n == 9)
  295.         __asm_copy_to_user_9(to, from, ret);
  296.     else if (n == 10)
  297.         __asm_copy_to_user_10(to, from, ret);
  298.     else if (n == 11)
  299.         __asm_copy_to_user_11(to, from, ret);
  300.     else if (n == 12)
  301.         __asm_copy_to_user_12(to, from, ret);
  302.     else if (n == 13)
  303.         __asm_copy_to_user_13(to, from, ret);
  304.     else if (n == 14)
  305.         __asm_copy_to_user_14(to, from, ret);
  306.     else if (n == 15)
  307.         __asm_copy_to_user_15(to, from, ret);
  308.     else if (n == 16)
  309.         __asm_copy_to_user_16(to, from, ret);
  310.     else if (n == 20)
  311.         __asm_copy_to_user_20(to, from, ret);
  312.     else if (n == 24)
  313.         __asm_copy_to_user_24(to, from, ret);
  314.     else
  315.         ret = __generic_copy_to_user(to, from, n);
  316.  
  317.     return ret;
  318. }
  319.  
  320. /* No switch, please.  */
  321.  
  322. static inline unsigned long
  323. __constant_clear_user(void __user *to, unsigned long n)
  324. {
  325.     unsigned long ret = 0;
  326.     if (n == 0)
  327.         ;
  328.     else if (n == 1)
  329.         __asm_clear_1(to, ret);
  330.     else if (n == 2)
  331.         __asm_clear_2(to, ret);
  332.     else if (n == 3)
  333.         __asm_clear_3(to, ret);
  334.     else if (n == 4)
  335.         __asm_clear_4(to, ret);
  336.     else if (n == 8)
  337.         __asm_clear_8(to, ret);
  338.     else if (n == 12)
  339.         __asm_clear_12(to, ret);
  340.     else if (n == 16)
  341.         __asm_clear_16(to, ret);
  342.     else if (n == 20)
  343.         __asm_clear_20(to, ret);
  344.     else if (n == 24)
  345.         __asm_clear_24(to, ret);
  346.     else
  347.         ret = __generic_clear_user(to, n);
  348.  
  349.     return ret;
  350. }
  351.  
  352.  
  353. #define clear_user(to, n)            \
  354. (__builtin_constant_p(n) ?            \
  355.  __constant_clear_user(to, n) :            \
  356.  __generic_clear_user(to, n))
  357.  
  358. #define copy_from_user(to, from, n)        \
  359. (__builtin_constant_p(n) ?            \
  360.  __constant_copy_from_user(to, from, n) :    \
  361.  __generic_copy_from_user(to, from, n))
  362.  
  363. #define copy_to_user(to, from, n)        \
  364. (__builtin_constant_p(n) ?            \
  365.  __constant_copy_to_user(to, from, n) :        \
  366.  __generic_copy_to_user(to, from, n))
  367.  
  368. /* We let the __ versions of copy_from/to_user inline, because they're often
  369.  * used in fast paths and have only a small space overhead.
  370.  */
  371.  
  372. static inline unsigned long
  373. __generic_copy_from_user_nocheck(void *to, const void __user *from,
  374.                  unsigned long n)
  375. {
  376.     return __copy_user_zeroing(to,from,n);
  377. }
  378.  
  379. static inline unsigned long
  380. __generic_copy_to_user_nocheck(void __user *to, const void *from,
  381.                    unsigned long n)
  382. {
  383.     return __copy_user(to,from,n);
  384. }
  385.  
  386. static inline unsigned long
  387. __generic_clear_user_nocheck(void __user *to, unsigned long n)
  388. {
  389.     return __do_clear_user(to,n);
  390. }
  391.  
  392. /* without checking */
  393.  
  394. #define __copy_to_user(to,from,n)   __generic_copy_to_user_nocheck((to),(from),(n))
  395. #define __copy_from_user(to,from,n) __generic_copy_from_user_nocheck((to),(from),(n))
  396. #define __copy_to_user_inatomic __copy_to_user
  397. #define __copy_from_user_inatomic __copy_from_user
  398. #define __clear_user(to,n) __generic_clear_user_nocheck((to),(n))
  399.  
  400. #define strlen_user(str)    strnlen_user((str), 0x7ffffffe)
  401.  
  402. #endif  /* __ASSEMBLY__ */
  403.  
  404. #endif    /* _CRIS_UACCESS_H */
  405.