home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-arm26 / uaccess.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  10.7 KB  |  294 lines

  1. #ifndef _ASMARM_UACCESS_H
  2. #define _ASMARM_UACCESS_H
  3.  
  4. /*
  5.  * User space memory access functions
  6.  */
  7. #include <linux/sched.h>
  8. #include <asm/errno.h>
  9.  
  10. #define VERIFY_READ 0
  11. #define VERIFY_WRITE 1
  12.  
  13. /*
  14.  * The exception table consists of pairs of addresses: the first is the
  15.  * address of an instruction that is allowed to fault, and the second is
  16.  * the address at which the program should continue.  No registers are
  17.  * modified, so it is entirely up to the continuation code to figure out
  18.  * what to do.
  19.  *
  20.  * All the routines below use bits of fixup code that are out of line
  21.  * with the main instruction path.  This means when everything is well,
  22.  * we don't even have to jump over them.  Further, they do not intrude
  23.  * on our cache or tlb entries.
  24.  */
  25.  
  26. struct exception_table_entry
  27. {
  28.     unsigned long insn, fixup;
  29. };
  30.  
  31. /* Returns 0 if exception not found and fixup otherwise.  */
  32. extern unsigned long search_exception_table(unsigned long);
  33. extern int fixup_exception(struct pt_regs *regs);
  34.  
  35. #define get_ds()    (KERNEL_DS)
  36. #define get_fs()    (current_thread_info()->addr_limit)
  37. #define segment_eq(a,b)    ((a) == (b))
  38.  
  39. #include <asm/uaccess-asm.h>
  40.  
  41. #define access_ok(type,addr,size)    (__range_ok(addr,size) == 0)
  42.  
  43. /*
  44.  * Single-value transfer routines.  They automatically use the right
  45.  * size if we just have the right pointer type.  Note that the functions
  46.  * which read from user space (*get_*) need to take care not to leak
  47.  * kernel data even if the calling code is buggy and fails to check
  48.  * the return value.  This means zeroing out the destination variable
  49.  * or buffer on error.  Normally this is done out of line by the
  50.  * fixup code, but there are a few places where it intrudes on the
  51.  * main code path.  When we only write to user space, there is no
  52.  * problem.
  53.  *
  54.  * The "__xxx" versions of the user access functions do not verify the
  55.  * address space - it must have been done previously with a separate
  56.  * "access_ok()" call.
  57.  *
  58.  * The "xxx_error" versions set the third argument to EFAULT if an
  59.  * error occurs, and leave it unchanged on success.  Note that these
  60.  * versions are void (ie, don't return a value as such).
  61.  */
  62.  
  63. extern int __get_user_1(void *);
  64. extern int __get_user_2(void *);
  65. extern int __get_user_4(void *);
  66. extern int __get_user_8(void *);
  67. extern int __get_user_bad(void);
  68.  
  69. #define __get_user_x(__r1,__p,__e,__s,__i...)                \
  70.        __asm__ __volatile__ ("bl    __get_user_" #__s        \
  71.         : "=&r" (__e), "=r" (__r1)                \
  72.         : "0" (__p)                        \
  73.         : __i)
  74.  
  75. #define get_user(x,p)                            \
  76.     ({                                \
  77.         const register typeof(*(p)) *__p asm("r0") = (p);    \
  78.         register typeof(*(p)) __r1 asm("r1");            \
  79.         register int __e asm("r0");                \
  80.         switch (sizeof(*(p))) {                    \
  81.         case 1:                            \
  82.             __get_user_x(__r1, __p, __e, 1, "lr");        \
  83.                    break;                        \
  84.         case 2:                            \
  85.             __get_user_x(__r1, __p, __e, 2, "r2", "lr");    \
  86.             break;                        \
  87.         case 4:                            \
  88.                    __get_user_x(__r1, __p, __e, 4, "lr");        \
  89.             break;                        \
  90.         case 8:                            \
  91.             __get_user_x(__r1, __p, __e, 8, "lr");        \
  92.                    break;                        \
  93.         default: __e = __get_user_bad(); break;            \
  94.         }                            \
  95.         x = __r1;                        \
  96.         __e;                            \
  97.     })
  98.  
  99.  
  100. #define __get_user(x,ptr)                                               \
  101. ({                                                                      \
  102.         long __gu_err = 0;                                              \
  103.         __get_user_err((x),(ptr),__gu_err);                             \
  104.         __gu_err;                                                       \
  105. })
  106.  
  107. #define __get_user_error(x,ptr,err)                                     \
  108. ({                                                                      \
  109.         __get_user_err((x),(ptr),err);                                  \
  110.         (void) 0;                                                       \
  111. })
  112.  
  113. #define __get_user_err(x,ptr,err)                                       \
  114. do {                                                                    \
  115.         unsigned long __gu_addr = (unsigned long)(ptr);                 \
  116.         unsigned long __gu_val;                                         \
  117.         switch (sizeof(*(ptr))) {                                       \
  118.         case 1: __get_user_asm_byte(__gu_val,__gu_addr,err);    break;  \
  119.         case 2: __get_user_asm_half(__gu_val,__gu_addr,err);    break;  \
  120.         case 4: __get_user_asm_word(__gu_val,__gu_addr,err);    break;  \
  121.         default: (__gu_val) = __get_user_bad();                         \
  122.         }                                                               \
  123.         (x) = (__typeof__(*(ptr)))__gu_val;                             \
  124. } while (0)
  125.  
  126. extern int __put_user_1(void *, unsigned int);
  127. extern int __put_user_2(void *, unsigned int);
  128. extern int __put_user_4(void *, unsigned int);
  129. extern int __put_user_8(void *, unsigned long long);
  130. extern int __put_user_bad(void);
  131.  
  132. #define __put_user_x(__r1,__p,__e,__s)                                  \
  133.            __asm__ __volatile__ (                                       \
  134.                 __asmeq("%0", "r0") __asmeq("%2", "r1")                 \
  135.                 "bl     __put_user_" #__s                               \
  136.                 : "=&r" (__e)                                           \
  137.                 : "0" (__p), "r" (__r1)                                 \
  138.                 : "ip", "lr", "cc")
  139.  
  140. #define put_user(x,p)                                                   \
  141.         ({                                                              \
  142.                 const register typeof(*(p)) __r1 asm("r1") = (x);       \
  143.                 const register typeof(*(p)) *__p asm("r0") = (p);       \
  144.                 register int __e asm("r0");                             \
  145.                 switch (sizeof(*(__p))) {                               \
  146.                 case 1:                                                 \
  147.                         __put_user_x(__r1, __p, __e, 1);                \
  148.                         break;                                          \
  149.                 case 2:                                                 \
  150.                         __put_user_x(__r1, __p, __e, 2);                \
  151.                         break;                                          \
  152.                 case 4:                                                 \
  153.                         __put_user_x(__r1, __p, __e, 4);                \
  154.                         break;                                          \
  155.                 case 8:                                                 \
  156.                         __put_user_x(__r1, __p, __e, 8);                \
  157.                         break;                                          \
  158.                 default: __e = __put_user_bad(); break;                 \
  159.                 }                                                       \
  160.                 __e;                                                    \
  161.         })
  162.  
  163. #if 0
  164. /*********************   OLD METHOD *******************/
  165. #define __put_user_x(__r1,__p,__e,__s,__i...)                \
  166.        __asm__ __volatile__ ("bl    __put_user_" #__s        \
  167.         : "=&r" (__e)                        \
  168.         : "0" (__p), "r" (__r1)                    \
  169.         : __i)
  170.  
  171. #define put_user(x,p)                            \
  172.     ({                                \
  173.         const register typeof(*(p)) __r1 asm("r1") = (x);    \
  174.         const register typeof(*(p)) *__p asm("r0") = (p);    \
  175.         register int __e asm("r0");                \
  176.         switch (sizeof(*(p))) {                    \
  177.         case 1:                            \
  178.             __put_user_x(__r1, __p, __e, 1, "r2", "lr");    \
  179.             break;                        \
  180.         case 2:                            \
  181.             __put_user_x(__r1, __p, __e, 2, "r2", "lr");    \
  182.             break;                        \
  183.         case 4:                            \
  184.             __put_user_x(__r1, __p, __e, 4, "r2", "lr");    \
  185.             break;                        \
  186.         case 8:                            \
  187.             __put_user_x(__r1, __p, __e, 8, "r2", "ip", "lr");    \
  188.             break;                        \
  189.         default: __e = __put_user_bad(); break;            \
  190.         }                            \
  191.         __e;                            \
  192.     })
  193. /*************************************************/
  194. #endif
  195.  
  196. #define __put_user(x,ptr)                                               \
  197. ({                                                                      \
  198.         long __pu_err = 0;                                              \
  199.         __put_user_err((x),(ptr),__pu_err);                             \
  200.         __pu_err;                                                       \
  201. })
  202.  
  203. #define __put_user_error(x,ptr,err)                                     \
  204. ({                                                                      \
  205.         __put_user_err((x),(ptr),err);                                  \
  206.         (void) 0;                                                       \
  207. })
  208.  
  209. #define __put_user_err(x,ptr,err)                                       \
  210. do {                                                                    \
  211.         unsigned long __pu_addr = (unsigned long)(ptr);                 \
  212.         __typeof__(*(ptr)) __pu_val = (x);                              \
  213.         switch (sizeof(*(ptr))) {                                       \
  214.         case 1: __put_user_asm_byte(__pu_val,__pu_addr,err);    break;  \
  215.         case 2: __put_user_asm_half(__pu_val,__pu_addr,err);    break;  \
  216.         case 4: __put_user_asm_word(__pu_val,__pu_addr,err);    break;  \
  217.         case 8: __put_user_asm_dword(__pu_val,__pu_addr,err);   break;  \
  218.         default: __put_user_bad();                                      \
  219.         }                                                               \
  220. } while (0)
  221.  
  222. static __inline__ unsigned long copy_from_user(void *to, const void *from, unsigned long n)
  223. {
  224.     if (access_ok(VERIFY_READ, from, n))
  225.         __do_copy_from_user(to, from, n);
  226.     else /* security hole - plug it */
  227.         memzero(to, n);
  228.     return n;
  229. }
  230.  
  231. static __inline__ unsigned long __copy_from_user(void *to, const void *from, unsigned long n)
  232. {
  233.     __do_copy_from_user(to, from, n);
  234.     return n;
  235. }
  236.  
  237. static __inline__ unsigned long copy_to_user(void *to, const void *from, unsigned long n)
  238. {
  239.     if (access_ok(VERIFY_WRITE, to, n))
  240.         __do_copy_to_user(to, from, n);
  241.     return n;
  242. }
  243.  
  244. static __inline__ unsigned long __copy_to_user(void *to, const void *from, unsigned long n)
  245. {
  246.     __do_copy_to_user(to, from, n);
  247.     return n;
  248. }
  249.  
  250. #define __copy_to_user_inatomic __copy_to_user
  251. #define __copy_from_user_inatomic __copy_from_user
  252.  
  253. static __inline__ unsigned long clear_user (void *to, unsigned long n)
  254. {
  255.     if (access_ok(VERIFY_WRITE, to, n))
  256.         __do_clear_user(to, n);
  257.     return n;
  258. }
  259.  
  260. static __inline__ unsigned long __clear_user (void *to, unsigned long n)
  261. {
  262.     __do_clear_user(to, n);
  263.     return n;
  264. }
  265.  
  266. static __inline__ long strncpy_from_user (char *dst, const char *src, long count)
  267. {
  268.     long res = -EFAULT;
  269.     if (access_ok(VERIFY_READ, src, 1))
  270.         __do_strncpy_from_user(dst, src, count, res);
  271.     return res;
  272. }
  273.  
  274. static __inline__ long __strncpy_from_user (char *dst, const char *src, long count)
  275. {
  276.     long res;
  277.     __do_strncpy_from_user(dst, src, count, res);
  278.     return res;
  279. }
  280.  
  281. #define strlen_user(s)    strnlen_user(s, ~0UL >> 1)
  282.  
  283. static inline long strnlen_user(const char *s, long n)
  284. {
  285.     unsigned long res = 0;
  286.  
  287.     if (__addr_ok(s))
  288.         __do_strnlen_user(s, n, res);
  289.  
  290.     return res;
  291. }
  292.  
  293. #endif /* _ASMARM_UACCESS_H */
  294.