uaccess.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:21k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  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.  * User space memory access functions
  15.  */
  16. #include <linux/sched.h>
  17. #define VERIFY_READ     0
  18. #define VERIFY_WRITE    1
  19. /*
  20.  * The fs value determines whether argument validity checking should be
  21.  * performed or not.  If get_fs() == USER_DS, checking is performed, with
  22.  * get_fs() == KERNEL_DS, checking is bypassed.
  23.  *
  24.  * For historical reasons, these macros are grossly misnamed.
  25.  */
  26. #define MAKE_MM_SEG(a)  ((mm_segment_t) { (a) })
  27. #define KERNEL_DS       MAKE_MM_SEG(0)
  28. #define USER_DS         MAKE_MM_SEG(1)
  29. #define get_ds()        (KERNEL_DS)
  30. #define get_fs()        (current->addr_limit)
  31. #define set_fs(x)       ({asm volatile("sar   4,%0"::"a" ((x).ar4)); 
  32.                          current->addr_limit = (x);})
  33. #define segment_eq(a,b) ((a).ar4 == (b).ar4)
  34. #define __access_ok(addr,size) (1)
  35. #define access_ok(type,addr,size) __access_ok(addr,size)
  36. extern inline int verify_area(int type, const void * addr, unsigned long size)
  37. {
  38.         return access_ok(type,addr,size)?0:-EFAULT;
  39. }
  40. /*
  41.  * The exception table consists of pairs of addresses: the first is the
  42.  * address of an instruction that is allowed to fault, and the second is
  43.  * the address at which the program should continue.  No registers are
  44.  * modified, so it is entirely up to the continuation code to figure out
  45.  * what to do.
  46.  *
  47.  * All the routines below use bits of fixup code that are out of line
  48.  * with the main instruction path.  This means when everything is well,
  49.  * we don't even have to jump over them.  Further, they do not intrude
  50.  * on our cache or tlb entries.
  51.  */
  52. struct exception_table_entry
  53. {
  54.         unsigned long insn, fixup;
  55. };
  56. /* Returns 0 if exception not found and fixup otherwise.  */
  57. extern unsigned long search_exception_table(unsigned long);
  58. /*
  59.  * These are the main single-value transfer routines.  They automatically
  60.  * use the right size if we just have the right pointer type.
  61.  */
  62. extern inline int __put_user_asm_8(__u64 x, void *ptr)
  63. {
  64.         int err;
  65.         __asm__ __volatile__ (  "   sr    %1,%1n"
  66. "   la    2,%2n"
  67. "   la    4,%0n"
  68.                                 "   sacf  512n"
  69.                                 "0: mvc   0(8,4),0(2)n"
  70.                                 "   sacf  0n"
  71. "1:n"
  72. ".section .fixup,"ax"n"
  73. "2: sacf  0n"
  74. "   lhi   %1,%h3n"
  75. "   bras  4,3fn"
  76. "   .long 1bn"
  77. "3: l     4,0(4)n"
  78. "   br    4n"
  79. ".previousn"
  80. ".section __ex_table,"a"n"
  81. "   .align 4n"
  82. "   .long  0b,2bn"
  83. ".previous"
  84.                                 : "=m" (*((__u32*) ptr)), "=&d" (err)
  85.                                 : "m" (x), "K" (-EFAULT)
  86.                                 : "cc", "2", "4" );
  87.         return err;
  88. }
  89. extern inline int __put_user_asm_4(__u32 x, void *ptr)
  90. {
  91.         int err;
  92.         __asm__ __volatile__ (  "   sr    %1,%1n"
  93. "   la    4,%0n"
  94.                                 "   sacf  512n"
  95.                                 "0: st    %2,0(4)n"
  96.                                 "   sacf  0n"
  97. "1:n"
  98. ".section .fixup,"ax"n"
  99. "2: sacf  0n"
  100. "   lhi   %1,%h3n"
  101. "   bras  4,3fn"
  102. "   .long 1bn"
  103. "3: l     4,0(4)n"
  104. "   br    4n"
  105. ".previousn"
  106. ".section __ex_table,"a"n"
  107. "   .align 4n"
  108. "   .long  0b,2bn"
  109. ".previous"
  110.                                 : "=m" (*((__u32*) ptr)) , "=&d" (err)
  111.                                 : "d" (x), "K" (-EFAULT)
  112.                                 : "cc", "4" );
  113.         return err;
  114. }
  115. extern inline int __put_user_asm_2(__u16 x, void *ptr)
  116. {
  117.         int err;
  118.         __asm__ __volatile__ (  "   sr    %1,%1n"
  119. "   la    4,%0n"
  120.                                 "   sacf  512n"
  121.                                 "0: sth   %2,0(4)n"
  122.                                 "   sacf  0n"
  123. "1:n"
  124. ".section .fixup,"ax"n"
  125. "2: sacf  0n"
  126. "   lhi   %1,%h3n"
  127. "   bras  4,3fn"
  128. "   .long 1bn"
  129. "3: l     4,0(4)n"
  130. "   br    4n"
  131. ".previousn"
  132. ".section __ex_table,"a"n"
  133. "   .align 4n"
  134. "   .long  0b,2bn"
  135. ".previous"
  136.                                 : "=m" (*((__u16*) ptr)) , "=&d" (err)
  137.                                 : "d" (x), "K" (-EFAULT)
  138.                                 : "cc", "4" );
  139.         return err;
  140. }
  141. extern inline int __put_user_asm_1(__u8 x, void *ptr)
  142. {
  143.         int err;
  144.         __asm__ __volatile__ (  "   sr    %1,%1n"
  145. "   la    4,%0n"
  146.                                 "   sacf  512n"
  147.                                 "0: stc   %2,0(4)n"
  148.                                 "   sacf  0n"
  149. "1:n"
  150. ".section .fixup,"ax"n"
  151. "2: sacf  0n"
  152. "   lhi   %1,%h3n"
  153. "   bras  4,3fn"
  154. "   .long 1bn"
  155. "3: l     4,0(4)n"
  156. "   br    4n"
  157. ".previousn"
  158. ".section __ex_table,"a"n"
  159. "   .align 4n"
  160. "   .long  0b,2bn"
  161. ".previous"
  162.                                 : "=m" (*((__u8*) ptr)) , "=&d" (err)
  163.                                 : "d" (x), "K" (-EFAULT)
  164.                                 : "cc", "4" );
  165.         return err;
  166. }
  167. /*
  168.  * (u8)(u32) ... autsch, but that the only way we can suppress the
  169.  * warnings when compiling binfmt_elf.c
  170.  */
  171. #define __put_user(x, ptr)                                      
  172. ({                                                              
  173.         __typeof__(*(ptr)) *__pu_addr = (ptr);                  
  174.         __typeof__(*(ptr)) __x = (x);                           
  175.         int __pu_err;                                           
  176.         switch (sizeof (*(ptr))) {                              
  177.         case 1:                                                 
  178.                 __pu_err = __put_user_asm_1((__u8)(__u32) __x,  
  179.                                             __pu_addr);         
  180.                 break;                                          
  181.         case 2:                                                 
  182.                 __pu_err = __put_user_asm_2((__u16)(__u32) __x, 
  183.                                             __pu_addr);         
  184.                 break;                                          
  185.         case 4:                                                 
  186.                 __pu_err = __put_user_asm_4((__u32) __x,        
  187.                                             __pu_addr);         
  188.                 break;                                          
  189.         case 8:                                                 
  190.                 __pu_err = __put_user_asm_8((__u64) __x,        
  191.                                             __pu_addr);         
  192.                 break;                                          
  193.         default:                                                
  194.                 __pu_err = __put_user_bad();                    
  195.                 break;                                          
  196.          }                                                      
  197.         __pu_err;                                               
  198. })
  199. #define put_user(x, ptr) __put_user(x, ptr)
  200. extern int __put_user_bad(void);
  201. #define __get_user_asm_8(x, ptr, err)                                      
  202. ({                                                                         
  203.         __asm__ __volatile__ (  "   sr    %1,%1n"                         
  204. "   la    2,%0n"    
  205.                                 "   la    4,%2n"                          
  206.                                 "   sacf  512n"                           
  207.                                 "0: mvc   0(8,2),0(4)n"                   
  208.                                 "   sacf  0n"                             
  209.                                 "1:n"                                     
  210.                                 ".section .fixup,"ax"n"                 
  211.                                 "2: sacf  0n"                             
  212.                                 "   lhi   %1,%h3n"                        
  213.                                 "   bras  4,3fn"                          
  214.                                 "   .long 1bn"                            
  215.                                 "3: l     4,0(4)n"                        
  216.                                 "   br    4n"                             
  217.                                 ".previousn"                              
  218.                                 ".section __ex_table,"a"n"              
  219.                                 "   .align 4n"                            
  220.                                 "   .long 0b,2bn"                         
  221.                                 ".previous"                                
  222.                                 : "=m" (x) , "=&d" (err)                   
  223.                                 : "m" (*(const __u64*)(ptr)),"K" (-EFAULT) 
  224.                                 : "cc", "2", "4" );                        
  225. })
  226. #define __get_user_asm_4(x, ptr, err)                                      
  227. ({                                                                         
  228.         __asm__ __volatile__ (  "   sr    %1,%1n"                         
  229.                                 "   la    4,%2n"                          
  230.                                 "   sacf  512n"                           
  231.                                 "0: l     %0,0(4)n"                       
  232.                                 "   sacf  0n"                             
  233.                                 "1:n"                                     
  234.                                 ".section .fixup,"ax"n"                 
  235.                                 "2: sacf  0n"                             
  236.                                 "   lhi   %1,%h3n"                        
  237.                                 "   bras  4,3fn"                          
  238.                                 "   .long 1bn"                            
  239.                                 "3: l     4,0(4)n"                        
  240.                                 "   br    4n"                             
  241.                                 ".previousn"                              
  242.                                 ".section __ex_table,"a"n"              
  243.                                 "   .align 4n"                            
  244.                                 "   .long 0b,2bn"                         
  245.                                 ".previous"                                
  246.                                 : "=d" (x) , "=&d" (err)                   
  247.                                 : "m" (*(const __u32*)(ptr)),"K" (-EFAULT) 
  248.                                 : "cc", "4" );                             
  249. })
  250. #define __get_user_asm_2(x, ptr, err)                                      
  251. ({                                                                         
  252.         __asm__ __volatile__ (  "   sr    %1,%1n"                         
  253.                                 "   la    4,%2n"                          
  254.                                 "   sacf  512n"                           
  255.                                 "0: lh    %0,0(4)n"                       
  256.                                 "   sacf  0n"                             
  257.                                 "1:n"                                     
  258.                                 ".section .fixup,"ax"n"                 
  259.                                 "2: sacf  0n"                             
  260.                                 "   lhi   %1,%h3n"                        
  261.                                 "   bras  4,3fn"                          
  262.                                 "   .long 1bn"                            
  263.                                 "3: l     4,0(4)n"                        
  264.                                 "   br    4n"                             
  265.                                 ".previousn"                              
  266.                                 ".section __ex_table,"a"n"              
  267.                                 "   .align 4n"                            
  268.                                 "   .long 0b,2bn"                         
  269.                                 ".previous"                                
  270.                                 : "=d" (x) , "=&d" (err)                   
  271.                                 : "m" (*(const __u16*)(ptr)),"K" (-EFAULT) 
  272.                                 : "cc", "4" );                             
  273. })
  274. #define __get_user_asm_1(x, ptr, err)                                     
  275. ({                                                                        
  276.         __asm__ __volatile__ (  "   sr    %1,%1n"                        
  277.                                 "   la    4,%2n"                         
  278.                                 "   sr    %0,%0n"                        
  279.                                 "   sacf  512n"                          
  280.                                 "0: ic    %0,0(4)n"                      
  281.                                 "   sacf  0n"                            
  282.                                 "1:n"                                    
  283.                                 ".section .fixup,"ax"n"                
  284.                                 "2: sacf  0n"                            
  285.                                 "   lhi   %1,%h3n"                       
  286.                                 "   bras  4,3fn"                         
  287.                                 "   .long 1bn"                           
  288.                                 "3: l     4,0(4)n"                       
  289.                                 "   br    4n"                            
  290.                                 ".previousn"                             
  291.                                 ".section __ex_table,"a"n"             
  292.                                 "   .align 4n"                           
  293.                                 "   .long 0b,2bn"                        
  294.                                 ".previous"                               
  295.                                 : "=d" (x) , "=&d" (err)                  
  296.                                 : "m" (*(const __u8*)(ptr)),"K" (-EFAULT) 
  297.                                 : "cc", "4" );                            
  298. })
  299. #define __get_user(x, ptr)                                      
  300. ({                                                              
  301.         __typeof__(ptr) __gu_addr = (ptr);                      
  302.         __typeof__(*(ptr)) __x;                                 
  303.         int __gu_err;                                           
  304.         switch (sizeof(*(__gu_addr))) {                         
  305.         case 1:                                                 
  306.                 __get_user_asm_1(__x, __gu_addr, __gu_err);     
  307.                 break;                                          
  308.         case 2:                                                 
  309.                 __get_user_asm_2(__x, __gu_addr, __gu_err);     
  310.                 break;                                          
  311.         case 4:                                                 
  312.                 __get_user_asm_4(__x, __gu_addr, __gu_err);     
  313.                 break;                                          
  314.         case 8:                                                 
  315.                 __get_user_asm_8(__x, __gu_addr, __gu_err);     
  316.                 break;                                          
  317.         default:                                                
  318.                 __x = 0;                                        
  319.                 __gu_err = __get_user_bad();                    
  320.                 break;                                          
  321.         }                                                       
  322.         (x) = __x;                                              
  323.         __gu_err;                                               
  324. })
  325. #define get_user(x, ptr) __get_user(x, ptr)
  326. extern int __get_user_bad(void);
  327. /*
  328.  * access register are set up, that 4 points to secondary (user) , 2 to primary (kernel)
  329.  */
  330. extern long __copy_to_user_asm(const void *from, long n, const void *to);
  331. #define __copy_to_user(to, from, n)                             
  332. ({                                                              
  333.         __copy_to_user_asm(from, n, to);                        
  334. })
  335. #define copy_to_user(to, from, n)                               
  336. ({                                                              
  337.         long err = 0;                                           
  338.         __typeof__(n) __n = (n);                                
  339.         if (__access_ok(to,__n)) {                              
  340.                 err = __copy_to_user_asm(from, __n, to);        
  341.         }                                                       
  342.         else                                                    
  343.                 err = __n;                                      
  344.         err;                                                    
  345. })
  346. extern long __copy_from_user_asm(void *to, long n, const void *from);
  347. #define __copy_from_user(to, from, n)                           
  348. ({                                                              
  349.         __copy_from_user_asm(to, n, from);                      
  350. })
  351. #define copy_from_user(to, from, n)                             
  352. ({                                                              
  353.         long err = 0;                                           
  354.         __typeof__(n) __n = (n);                                
  355.         if (__access_ok(from,__n)) {                            
  356.                 err = __copy_from_user_asm(to, __n, from);      
  357.         }                                                       
  358.         else                                                    
  359.                 err = __n;                                      
  360.         err;                                                    
  361. })
  362. /*
  363.  * Copy a null terminated string from userspace.
  364.  */
  365. static inline long
  366. __strncpy_from_user(char *dst, const char *src, long count)
  367. {
  368.         int len;
  369.         __asm__ __volatile__ (  "   slr   %0,%0n"
  370. "   lr    2,%1n"
  371.                                 "   lr    4,%2n"
  372.                                 "   slr   3,3n"
  373.                                 "   sacf  512n"
  374.                                 "0: ic    3,0(%0,4)n"
  375.                                 "1: stc   3,0(%0,2)n"
  376.                                 "   ltr   3,3n"
  377.                                 "   jz    2fn"
  378.                                 "   ahi   %0,1n"
  379.                                 "   clr   %0,%3n"
  380.                                 "   jl    0bn"
  381.                                 "2: sacf  0n"
  382. ".section .fixup,"ax"n"
  383.                                 "3: lhi   %0,%h4n"
  384. "   basr  3,0n"
  385.                                 "   l     3,4f-.(3)n"
  386.                                 "   br    3n"
  387. "4: .long 2bn"
  388. ".previousn"
  389. ".section __ex_table,"a"n"
  390. "   .align 4n"
  391. "   .long  0b,3bn"
  392.                                 "   .long  1b,3bn"
  393. ".previous"
  394.                                 : "=&a" (len)
  395.                                 : "a" (dst), "d" (src), "d" (count),
  396.                                   "K" (-EFAULT)
  397.                                 : "2", "3", "4", "memory", "cc" );
  398.         return len;
  399. }
  400. static inline long
  401. strncpy_from_user(char *dst, const char *src, long count)
  402. {
  403.         long res = -EFAULT;
  404.         if (access_ok(VERIFY_READ, src, 1))
  405.                 res = __strncpy_from_user(dst, src, count);
  406.         return res;
  407. }
  408. /*
  409.  * Return the size of a string (including the ending 0)
  410.  *
  411.  * Return 0 for error
  412.  */
  413. static inline unsigned long
  414. strnlen_user(const char * src, unsigned long n)
  415. {
  416. __asm__ __volatile__ ("   alr   %0,%1n"
  417.       "   slr   0,0n"
  418.       "   lr    4,%1n"
  419.       "   sacf  512n"
  420.       "0: srst  %0,4n"
  421.       "   jo    0bn"
  422.       "   slr   %0,%1n"
  423.       "   ahi   %0,1n"
  424.       "   sacf  0n"
  425.                               "1:n"
  426.                               ".section .fixup,"ax"n"
  427.                               "2: sacf  0n"
  428.                               "   slr   %0,%0n"
  429.                               "   bras  4,3fn"
  430.                               "   .long 1bn"
  431.                               "3: l     4,0(4)n"
  432.                               "   br    4n"
  433.                               ".previousn"
  434.       ".section __ex_table,"a"n"
  435.       "   .align 4n"
  436.       "   .long  0b,2bn"
  437.       ".previous"
  438.       : "+&a" (n) : "d" (src)
  439.       : "cc", "0", "4" );
  440.         return n;
  441. }
  442. #define strlen_user(str) strnlen_user(str, ~0UL)
  443. /*
  444.  * Zero Userspace
  445.  */
  446. extern long __clear_user_asm(void *to, long n);
  447. #define __clear_user(to, n)                                     
  448. ({                                                              
  449.         __clear_user_asm(to, n);                                
  450. })
  451. static inline unsigned long
  452. clear_user(void *to, unsigned long n)
  453. {
  454.         if (access_ok(VERIFY_WRITE, to, n))
  455.                 n = __clear_user(to, n);
  456.         return n;
  457. }
  458. #endif                                 /* _S390_UACCESS_H                  */