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-cris / uaccess.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  12.5 KB  |  440 lines

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