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

  1. /*
  2.  *  include/asm-s390/uaccess.h
  3.  *
  4.  *  S390 version
  5.  *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
  6.  *    Author(s): Hartmut Penner (hp@de.ibm.com),
  7.  *               Martin Schwidefsky (schwidefsky@de.ibm.com)
  8.  *
  9.  *  Derived from "include/asm-i386/uaccess.h"
  10.  */
  11. #ifndef __S390_UACCESS_H
  12. #define __S390_UACCESS_H
  13.  
  14. /*
  15.  * User space memory access functions
  16.  */
  17. #include <linux/sched.h>
  18. #include <linux/errno.h>
  19.  
  20. #define VERIFY_READ     0
  21. #define VERIFY_WRITE    1
  22.  
  23.  
  24. /*
  25.  * The fs value determines whether argument validity checking should be
  26.  * performed or not.  If get_fs() == USER_DS, checking is performed, with
  27.  * get_fs() == KERNEL_DS, checking is bypassed.
  28.  *
  29.  * For historical reasons, these macros are grossly misnamed.
  30.  */
  31.  
  32. #define MAKE_MM_SEG(a)  ((mm_segment_t) { (a) })
  33.  
  34.  
  35. #define KERNEL_DS       MAKE_MM_SEG(0)
  36. #define USER_DS         MAKE_MM_SEG(1)
  37.  
  38. #define get_ds()        (KERNEL_DS)
  39. #define get_fs()        (current->thread.mm_segment)
  40.  
  41. #ifdef __s390x__
  42. #define set_fs(x) \
  43. ({                                    \
  44.     unsigned long __pto;                        \
  45.     current->thread.mm_segment = (x);                \
  46.     __pto = current->thread.mm_segment.ar4 ?            \
  47.         S390_lowcore.user_asce : S390_lowcore.kernel_asce;    \
  48.     asm volatile ("lctlg 7,7,%0" : : "m" (__pto) );            \
  49. })
  50. #else
  51. #define set_fs(x) \
  52. ({                                    \
  53.     unsigned long __pto;                        \
  54.     current->thread.mm_segment = (x);                \
  55.     __pto = current->thread.mm_segment.ar4 ?            \
  56.         S390_lowcore.user_asce : S390_lowcore.kernel_asce;    \
  57.     asm volatile ("lctl  7,7,%0" : : "m" (__pto) );            \
  58. })
  59. #endif
  60.  
  61. #define segment_eq(a,b) ((a).ar4 == (b).ar4)
  62.  
  63.  
  64. static inline int __access_ok(const void __user *addr, unsigned long size)
  65. {
  66.     return 1;
  67. }
  68. #define access_ok(type,addr,size) __access_ok(addr,size)
  69.  
  70. /*
  71.  * The exception table consists of pairs of addresses: the first is the
  72.  * address of an instruction that is allowed to fault, and the second is
  73.  * the address at which the program should continue.  No registers are
  74.  * modified, so it is entirely up to the continuation code to figure out
  75.  * what to do.
  76.  *
  77.  * All the routines below use bits of fixup code that are out of line
  78.  * with the main instruction path.  This means when everything is well,
  79.  * we don't even have to jump over them.  Further, they do not intrude
  80.  * on our cache or tlb entries.
  81.  */
  82.  
  83. struct exception_table_entry
  84. {
  85.         unsigned long insn, fixup;
  86. };
  87.  
  88. #ifndef __s390x__
  89. #define __uaccess_fixup \
  90.     ".section .fixup,\"ax\"\n"    \
  91.     "2: lhi    %0,%4\n"        \
  92.     "   bras   1,3f\n"        \
  93.     "   .long  1b\n"        \
  94.     "3: l      1,0(1)\n"        \
  95.     "   br     1\n"            \
  96.     ".previous\n"            \
  97.     ".section __ex_table,\"a\"\n"    \
  98.     "   .align 4\n"            \
  99.     "   .long  0b,2b\n"        \
  100.     ".previous"
  101. #define __uaccess_clobber "cc", "1"
  102. #else /* __s390x__ */
  103. #define __uaccess_fixup \
  104.     ".section .fixup,\"ax\"\n"    \
  105.     "2: lghi   %0,%4\n"        \
  106.     "   jg     1b\n"        \
  107.     ".previous\n"            \
  108.     ".section __ex_table,\"a\"\n"    \
  109.     "   .align 8\n"            \
  110.     "   .quad  0b,2b\n"        \
  111.     ".previous"
  112. #define __uaccess_clobber "cc"
  113. #endif /* __s390x__ */
  114.  
  115. /*
  116.  * These are the main single-value transfer routines.  They automatically
  117.  * use the right size if we just have the right pointer type.
  118.  */
  119. #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
  120. #define __put_user_asm(x, ptr, err) \
  121. ({                                \
  122.     err = 0;                        \
  123.     asm volatile(                        \
  124.         "0: mvcs  0(%1,%2),%3,%0\n"            \
  125.         "1:\n"                        \
  126.         __uaccess_fixup                    \
  127.         : "+&d" (err)                    \
  128.         : "d" (sizeof(*(ptr))), "a" (ptr), "Q" (x),    \
  129.           "K" (-EFAULT)                    \
  130.         : __uaccess_clobber );                \
  131. })
  132. #else
  133. #define __put_user_asm(x, ptr, err) \
  134. ({                                \
  135.     err = 0;                        \
  136.     asm volatile(                        \
  137.         "0: mvcs  0(%1,%2),0(%3),%0\n"            \
  138.         "1:\n"                        \
  139.         __uaccess_fixup                    \
  140.         : "+&d" (err)                    \
  141.         : "d" (sizeof(*(ptr))), "a" (ptr), "a" (&(x)),    \
  142.           "K" (-EFAULT), "m" (x)            \
  143.         : __uaccess_clobber );                \
  144. })
  145. #endif
  146.  
  147. #define __put_user(x, ptr) \
  148. ({                                \
  149.     __typeof__(*(ptr)) __x = (x);                \
  150.     int __pu_err;                        \
  151.         __chk_user_ptr(ptr);                                    \
  152.     switch (sizeof (*(ptr))) {                \
  153.     case 1:                            \
  154.     case 2:                            \
  155.     case 4:                            \
  156.     case 8:                            \
  157.         __put_user_asm(__x, ptr, __pu_err);        \
  158.         break;                        \
  159.     default:                        \
  160.         __put_user_bad();                \
  161.         break;                        \
  162.      }                            \
  163.     __pu_err;                        \
  164. })
  165.  
  166. #define put_user(x, ptr)                    \
  167. ({                                \
  168.     might_sleep();                        \
  169.     __put_user(x, ptr);                    \
  170. })
  171.  
  172.  
  173. extern int __put_user_bad(void) __attribute__((noreturn));
  174.  
  175. #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
  176. #define __get_user_asm(x, ptr, err) \
  177. ({                                \
  178.     err = 0;                        \
  179.     asm volatile (                        \
  180.         "0: mvcp  %O1(%2,%R1),0(%3),%0\n"        \
  181.         "1:\n"                        \
  182.         __uaccess_fixup                    \
  183.         : "+&d" (err), "=Q" (x)                \
  184.         : "d" (sizeof(*(ptr))), "a" (ptr),        \
  185.           "K" (-EFAULT)                    \
  186.         : __uaccess_clobber );                \
  187. })
  188. #else
  189. #define __get_user_asm(x, ptr, err) \
  190. ({                                \
  191.     err = 0;                        \
  192.     asm volatile (                        \
  193.         "0: mvcp  0(%2,%5),0(%3),%0\n"            \
  194.         "1:\n"                        \
  195.         __uaccess_fixup                    \
  196.         : "+&d" (err), "=m" (x)                \
  197.         : "d" (sizeof(*(ptr))), "a" (ptr),        \
  198.           "K" (-EFAULT), "a" (&(x))            \
  199.         : __uaccess_clobber );                \
  200. })
  201. #endif
  202.  
  203. #define __get_user(x, ptr)                    \
  204. ({                                \
  205.     int __gu_err;                        \
  206.         __chk_user_ptr(ptr);                                    \
  207.     switch (sizeof(*(ptr))) {                \
  208.     case 1: {                        \
  209.         unsigned char __x;                \
  210.         __get_user_asm(__x, ptr, __gu_err);        \
  211.         (x) = *(__force __typeof__(*(ptr)) *) &__x;    \
  212.         break;                        \
  213.     };                            \
  214.     case 2: {                        \
  215.         unsigned short __x;                \
  216.         __get_user_asm(__x, ptr, __gu_err);        \
  217.         (x) = *(__force __typeof__(*(ptr)) *) &__x;    \
  218.         break;                        \
  219.     };                            \
  220.     case 4: {                        \
  221.         unsigned int __x;                \
  222.         __get_user_asm(__x, ptr, __gu_err);        \
  223.         (x) = *(__force __typeof__(*(ptr)) *) &__x;    \
  224.         break;                        \
  225.     };                            \
  226.     case 8: {                        \
  227.         unsigned long long __x;                \
  228.         __get_user_asm(__x, ptr, __gu_err);        \
  229.         (x) = *(__force __typeof__(*(ptr)) *) &__x;    \
  230.         break;                        \
  231.     };                            \
  232.     default:                        \
  233.         __get_user_bad();                \
  234.         break;                        \
  235.     }                            \
  236.     __gu_err;                        \
  237. })
  238.  
  239. #define get_user(x, ptr)                    \
  240. ({                                \
  241.     might_sleep();                        \
  242.     __get_user(x, ptr);                    \
  243. })
  244.  
  245. extern int __get_user_bad(void) __attribute__((noreturn));
  246.  
  247. #define __put_user_unaligned __put_user
  248. #define __get_user_unaligned __get_user
  249.  
  250. extern long __copy_to_user_asm(const void *from, long n, void __user *to);
  251.  
  252. /**
  253.  * __copy_to_user: - Copy a block of data into user space, with less checking.
  254.  * @to:   Destination address, in user space.
  255.  * @from: Source address, in kernel space.
  256.  * @n:    Number of bytes to copy.
  257.  *
  258.  * Context: User context only.  This function may sleep.
  259.  *
  260.  * Copy data from kernel space to user space.  Caller must check
  261.  * the specified block with access_ok() before calling this function.
  262.  *
  263.  * Returns number of bytes that could not be copied.
  264.  * On success, this will be zero.
  265.  */
  266. static inline unsigned long
  267. __copy_to_user(void __user *to, const void *from, unsigned long n)
  268. {
  269.     return __copy_to_user_asm(from, n, to);
  270. }
  271.  
  272. #define __copy_to_user_inatomic __copy_to_user
  273. #define __copy_from_user_inatomic __copy_from_user
  274.  
  275. /**
  276.  * copy_to_user: - Copy a block of data into user space.
  277.  * @to:   Destination address, in user space.
  278.  * @from: Source address, in kernel space.
  279.  * @n:    Number of bytes to copy.
  280.  *
  281.  * Context: User context only.  This function may sleep.
  282.  *
  283.  * Copy data from kernel space to user space.
  284.  *
  285.  * Returns number of bytes that could not be copied.
  286.  * On success, this will be zero.
  287.  */
  288. static inline unsigned long
  289. copy_to_user(void __user *to, const void *from, unsigned long n)
  290. {
  291.     might_sleep();
  292.     if (access_ok(VERIFY_WRITE, to, n))
  293.         n = __copy_to_user(to, from, n);
  294.     return n;
  295. }
  296.  
  297. extern long __copy_from_user_asm(void *to, long n, const void __user *from);
  298.  
  299. /**
  300.  * __copy_from_user: - Copy a block of data from user space, with less checking.
  301.  * @to:   Destination address, in kernel space.
  302.  * @from: Source address, in user space.
  303.  * @n:    Number of bytes to copy.
  304.  *
  305.  * Context: User context only.  This function may sleep.
  306.  *
  307.  * Copy data from user space to kernel space.  Caller must check
  308.  * the specified block with access_ok() before calling this function.
  309.  *
  310.  * Returns number of bytes that could not be copied.
  311.  * On success, this will be zero.
  312.  *
  313.  * If some data could not be copied, this function will pad the copied
  314.  * data to the requested size using zero bytes.
  315.  */
  316. static inline unsigned long
  317. __copy_from_user(void *to, const void __user *from, unsigned long n)
  318. {
  319.     return __copy_from_user_asm(to, n, from);
  320. }
  321.  
  322. /**
  323.  * copy_from_user: - Copy a block of data from user space.
  324.  * @to:   Destination address, in kernel space.
  325.  * @from: Source address, in user space.
  326.  * @n:    Number of bytes to copy.
  327.  *
  328.  * Context: User context only.  This function may sleep.
  329.  *
  330.  * Copy data from user space to kernel space.
  331.  *
  332.  * Returns number of bytes that could not be copied.
  333.  * On success, this will be zero.
  334.  *
  335.  * If some data could not be copied, this function will pad the copied
  336.  * data to the requested size using zero bytes.
  337.  */
  338. static inline unsigned long
  339. copy_from_user(void *to, const void __user *from, unsigned long n)
  340. {
  341.     might_sleep();
  342.     if (access_ok(VERIFY_READ, from, n))
  343.         n = __copy_from_user(to, from, n);
  344.     else
  345.         memset(to, 0, n);
  346.     return n;
  347. }
  348.  
  349. extern unsigned long __copy_in_user_asm(const void __user *from, long n,
  350.                             void __user *to);
  351.  
  352. static inline unsigned long
  353. __copy_in_user(void __user *to, const void __user *from, unsigned long n)
  354. {
  355.     return __copy_in_user_asm(from, n, to);
  356. }
  357.  
  358. static inline unsigned long
  359. copy_in_user(void __user *to, const void __user *from, unsigned long n)
  360. {
  361.     might_sleep();
  362.     if (__access_ok(from,n) && __access_ok(to,n))
  363.         n = __copy_in_user_asm(from, n, to);
  364.     return n;
  365. }
  366.  
  367. /*
  368.  * Copy a null terminated string from userspace.
  369.  */
  370. extern long __strncpy_from_user_asm(long count, char *dst,
  371.                     const char __user *src);
  372.  
  373. static inline long
  374. strncpy_from_user(char *dst, const char __user *src, long count)
  375. {
  376.         long res = -EFAULT;
  377.         might_sleep();
  378.         if (access_ok(VERIFY_READ, src, 1))
  379.                 res = __strncpy_from_user_asm(count, dst, src);
  380.         return res;
  381. }
  382.  
  383.  
  384. extern long __strnlen_user_asm(long count, const char __user *src);
  385.  
  386. static inline unsigned long
  387. strnlen_user(const char __user * src, unsigned long n)
  388. {
  389.     might_sleep();
  390.     return __strnlen_user_asm(n, src);
  391. }
  392.  
  393. /**
  394.  * strlen_user: - Get the size of a string in user space.
  395.  * @str: The string to measure.
  396.  *
  397.  * Context: User context only.  This function may sleep.
  398.  *
  399.  * Get the size of a NUL-terminated string in user space.
  400.  *
  401.  * Returns the size of the string INCLUDING the terminating NUL.
  402.  * On exception, returns 0.
  403.  *
  404.  * If there is a limit on the length of a valid string, you may wish to
  405.  * consider using strnlen_user() instead.
  406.  */
  407. #define strlen_user(str) strnlen_user(str, ~0UL)
  408.  
  409. /*
  410.  * Zero Userspace
  411.  */
  412.  
  413. extern long __clear_user_asm(void __user *to, long n);
  414.  
  415. static inline unsigned long
  416. __clear_user(void __user *to, unsigned long n)
  417. {
  418.     return __clear_user_asm(to, n);
  419. }
  420.  
  421. static inline unsigned long
  422. clear_user(void __user *to, unsigned long n)
  423. {
  424.     might_sleep();
  425.     if (access_ok(VERIFY_WRITE, to, n))
  426.         n = __clear_user_asm(to, n);
  427.     return n;
  428. }
  429.  
  430. #endif /* __S390_UACCESS_H */
  431.