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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  include/asm-s390/uaccess.h
  3.  *
  4.  *  S390 version
  5.  *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
  6.  *    Author(s): Hartmut Penner (hpenner@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(s) ((mm_segment_t) { (s) })
  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    4,%0n"
  67.                                 "   sacf  512n"
  68.                                 "0: stg   %2,0(4)n"
  69.                                 "1: sacf  0n"
  70. ".section .fixup,"ax"n"
  71. "2: lhi   %1,%h3n"
  72. "   jg    1bn"
  73. ".previousn"
  74. ".section __ex_table,"a"n"
  75. "   .align 8n"
  76. "   .quad  0b,2bn"
  77. ".previous"
  78.                                 : "=m" (*((__u64*) ptr)) , "=&d" (err)
  79.                                 : "d" (x), "K" (-EFAULT)
  80.                                 : "cc", "4" );
  81.         return err;
  82. }
  83. extern inline int __put_user_asm_4(__u32 x, void *ptr)
  84. {
  85.         int err;
  86.         __asm__ __volatile__ (  "   sr    %1,%1n"
  87. "   la    4,%0n"
  88.                                 "   sacf  512n"
  89.                                 "0: st    %2,0(4)n"
  90.                                 "1: sacf  0n"
  91. ".section .fixup,"ax"n"
  92. "2: lhi   %1,%h3n"
  93. "   jg    1bn"
  94. ".previousn"
  95. ".section __ex_table,"a"n"
  96. "   .align 8n"
  97. "   .quad  0b,2bn"
  98. ".previous"
  99.                                 : "=m" (*((__u32*) ptr)) , "=&d" (err)
  100.                                 : "d" (x), "K" (-EFAULT)
  101.                                 : "cc", "4" );
  102.         return err;
  103. }
  104. extern inline int __put_user_asm_2(__u16 x, void *ptr)
  105. {
  106.         int err;
  107.         __asm__ __volatile__ (  "   sr    %1,%1n"
  108. "   la    4,%0n"
  109.                                 "   sacf  512n"
  110.                                 "0: sth   %2,0(4)n"
  111.                                 "1: sacf  0n"
  112. ".section .fixup,"ax"n"
  113. "2: lhi   %1,%h3n"
  114. "   jg    1bn"
  115. ".previousn"
  116. ".section __ex_table,"a"n"
  117. "   .align 8n"
  118. "   .quad  0b,2bn"
  119. ".previous"
  120.                                 : "=m" (*((__u16*) ptr)) , "=&d" (err)
  121.                                 : "d" (x), "K" (-EFAULT)
  122.                                 : "cc", "4" );
  123.         return err;
  124. }
  125. extern inline int __put_user_asm_1(__u8 x, void *ptr)
  126. {
  127.         int err;
  128.         __asm__ __volatile__ (  "   sr    %1,%1n"
  129. "   la    4,%0n"
  130.                                 "   sacf  512n"
  131.                                 "0: stc   %2,0(4)n"
  132.                                 "1: sacf  0n"
  133. ".section .fixup,"ax"n"
  134. "2: lhi   %1,%h3n"
  135. "   jg    1bn"
  136. ".previousn"
  137. ".section __ex_table,"a"n"
  138. "   .align 8n"
  139. "   .quad  0b,2bn"
  140. ".previous"
  141.                                 : "=m" (*((__u8*) ptr)) , "=&d" (err)
  142.                                 : "d" (x), "K" (-EFAULT)
  143.                                 : "cc", "1", "4" );
  144.         return err;
  145. }
  146. /*
  147.  * (u?)(u64) ... autsch, but that the only way we can suppress the
  148.  * warnings when compiling binfmt_elf.c
  149.  */
  150. #define __put_user(x, ptr)                                      
  151. ({                                                              
  152.         __typeof__(*(ptr)) *__pu_addr = (ptr);                  
  153.         __typeof__(*(ptr)) __x = (x);                           
  154.         int __pu_err;                                           
  155.         switch (sizeof (*(__pu_addr))) {                        
  156.         case 1:                                                 
  157.                 __pu_err = __put_user_asm_1((__u8)(__u64)(__x), 
  158.                                             __pu_addr);         
  159.                 break;                                          
  160.         case 2:                                                 
  161.                 __pu_err = __put_user_asm_2((__u16)(__u64)(__x),
  162.                                             __pu_addr);         
  163.                 break;                                          
  164.         case 4:                                                 
  165.                 __pu_err = __put_user_asm_4((__u32)(__u64)(__x),
  166.                                             __pu_addr);         
  167.                 break;                                          
  168.         case 8:                                                 
  169.                 __pu_err = __put_user_asm_8((__u64)(__x),       
  170.                                             __pu_addr);         
  171.                 break;                                          
  172.         default:                                                
  173.                 __pu_err = __put_user_bad();                    
  174.                 break;                                          
  175.          }                                                      
  176.         __pu_err;                                               
  177. })
  178. #define put_user(x, ptr) __put_user(x, ptr)
  179. extern int __put_user_bad(void);
  180. #define __get_user_asm_8(x, ptr, err)                                      
  181. ({                                                                         
  182.         __asm__ __volatile__ (  "   sr    %1,%1n"                         
  183.                                 "   la    4,%2n"                          
  184.                                 "   sacf  512n"                           
  185.                                 "0: lg    %0,0(4)n"                       
  186.                                 "1: sacf  0n"                             
  187.                                 ".section .fixup,"ax"n"                 
  188.                                 "2: lhi   %1,%h3n"                        
  189.                                 "   jg    1bn"                            
  190.                                 ".previousn"                              
  191.                                 ".section __ex_table,"a"n"              
  192.                                 "   .align 8n"                            
  193.                                 "   .quad 0b,2bn"                         
  194.                                 ".previous"                                
  195.                                 : "=d" (x) , "=&d" (err)                   
  196.                                 : "m" (*(const __u64*)(ptr)),"K" (-EFAULT) 
  197.                                 : "cc", "4" );                             
  198. })
  199. #define __get_user_asm_4(x, ptr, err)                                      
  200. ({                                                                         
  201.         __asm__ __volatile__ (  "   sr    %1,%1n"                         
  202.                                 "   la    4,%2n"                          
  203.                                 "   sacf  512n"                           
  204.                                 "0: l     %0,0(4)n"                       
  205.                                 "1: sacf  0n"                             
  206.                                 ".section .fixup,"ax"n"                 
  207.                                 "2: lhi   %1,%h3n"                        
  208.                                 "   jg    1bn"                            
  209.                                 ".previousn"                              
  210.                                 ".section __ex_table,"a"n"              
  211.                                 "   .align 8n"                            
  212.                                 "   .quad 0b,2bn"                         
  213.                                 ".previous"                                
  214.                                 : "=d" (x) , "=&d" (err)                   
  215.                                 : "m" (*(const __u32*)(ptr)),"K" (-EFAULT) 
  216.                                 : "cc", "4" );                             
  217. })
  218. #define __get_user_asm_2(x, ptr, err)                                      
  219. ({                                                                         
  220.         __asm__ __volatile__ (  "   sr    %1,%1n"                         
  221.                                 "   la    4,%2n"                          
  222.                                 "   sacf  512n"                           
  223.                                 "0: lh    %0,0(4)n"                       
  224.                                 "1: sacf  0n"                             
  225.                                 ".section .fixup,"ax"n"                 
  226.                                 "2: lhi   %1,%h3n"                        
  227.                                 "   jg    1bn"                            
  228.                                 ".previousn"                              
  229.                                 ".section __ex_table,"a"n"              
  230.                                 "   .align 8n"                            
  231.                                 "   .quad 0b,2bn"                         
  232.                                 ".previous"                                
  233.                                 : "=d" (x) , "=&d" (err)                   
  234.                                 : "m" (*(const __u16*)(ptr)),"K" (-EFAULT) 
  235.                                 : "cc", "4" );                             
  236. })
  237. #define __get_user_asm_1(x, ptr, err)                                     
  238. ({                                                                        
  239.         __asm__ __volatile__ (  "   sr    %1,%1n"                        
  240.                                 "   la    4,%2n"                         
  241.                                 "   sr    %0,%0n"                        
  242.                                 "   sacf  512n"                          
  243.                                 "0: ic    %0,0(4)n"                      
  244.                                 "1: sacf  0n"                            
  245.                                 ".section .fixup,"ax"n"                
  246.                                 "2: lhi   %1,%h3n"                       
  247.                                 "   jg    1bn"                           
  248.                                 ".previousn"                             
  249.                                 ".section __ex_table,"a"n"             
  250.                                 "   .align 8n"                           
  251.                                 "   .quad 0b,2bn"                        
  252.                                 ".previous"                               
  253.                                 : "=d" (x) , "=&d" (err)                  
  254.                                 : "m" (*(const __u8*)(ptr)),"K" (-EFAULT) 
  255.                                 : "cc", "4" );                            
  256. })
  257. #define __get_user(x, ptr)                                      
  258. ({                                                              
  259.         __typeof__(ptr) __gu_addr = (ptr);                      
  260.         __typeof__(*(ptr)) __x;                                 
  261.         int __gu_err;                                           
  262.         switch (sizeof(*(ptr))) {                               
  263.         case 1:                                                 
  264.                 __get_user_asm_1(__x,__gu_addr,__gu_err);       
  265.                 break;                                          
  266.         case 2:                                                 
  267.                 __get_user_asm_2(__x,__gu_addr,__gu_err);       
  268.                 break;                                          
  269.         case 4:                                                 
  270.                 __get_user_asm_4(__x,__gu_addr,__gu_err);       
  271.                 break;                                          
  272.         case 8:                                                 
  273.                 __get_user_asm_8(__x,__gu_addr,__gu_err);       
  274.                 break;                                          
  275.         default:                                                
  276.                 __x = 0;                                        
  277.                 __gu_err = __get_user_bad();                    
  278.                 break;                                          
  279.         }                                                       
  280.         (x) = __x;                                              
  281.         __gu_err;                                               
  282. })
  283. #define get_user(x, ptr) __get_user(x, ptr)
  284. extern int __get_user_bad(void);
  285. /*
  286.  * access register are set up, that 4 points to secondary (user) , 2 to primary (kernel)
  287.  */
  288. extern long __copy_to_user_asm(const void *from, long n, void *to);
  289. #define __copy_to_user(to, from, n)                             
  290. ({                                                              
  291.         __copy_to_user_asm(from, n, to);                        
  292. })
  293. #define copy_to_user(to, from, n)                               
  294. ({                                                              
  295.         long err = 0;                                           
  296.         __typeof__(n) __n = (n);                                
  297.         if (__access_ok(to,__n)) {                              
  298.                 err = __copy_to_user_asm(from, __n, to);        
  299.         }                                                       
  300.         else                                                    
  301.                 err = __n;                                      
  302.         err;                                                    
  303. })
  304. extern long __copy_from_user_asm(void *to, long n, const void *from);
  305. #define __copy_from_user(to, from, n)                           
  306. ({                                                              
  307.         __copy_from_user_asm(to, n, from);                      
  308. })
  309. #define copy_from_user(to, from, n)                             
  310. ({                                                              
  311.         long err = 0;                                           
  312.         __typeof__(n) __n = (n);                                
  313.         if (__access_ok(from,__n)) {                            
  314.                 err = __copy_from_user_asm(to, __n, from);      
  315.         }                                                       
  316.         else                                                    
  317.                 err = __n;                                      
  318.         err;                                                    
  319. })
  320. /*
  321.  * Copy a null terminated string from userspace.
  322.  */
  323. static inline long
  324. __strncpy_from_user(char *dst, const char *src, long count)
  325. {
  326.         long len;
  327.         __asm__ __volatile__ (  "   slgr  %0,%0n"
  328. "   lgr   2,%1n"
  329.                                 "   lgr   4,%2n"
  330.                                 "   slr   3,3n"
  331.                                 "   sacf  512n"
  332.                                 "0: ic    3,0(%0,4)n"
  333.                                 "1: stc   3,0(%0,2)n"
  334.                                 "   ltr   3,3n"
  335.                                 "   jz    2fn"
  336.                                 "   aghi  %0,1n"
  337.                                 "   cgr   %0,%3n"
  338.                                 "   jl    0bn"
  339.                                 "2: sacf  0n"
  340. ".section .fixup,"ax"n"
  341. "3: lghi  %0,%h4n"
  342. "   jg    2bn"  
  343. ".previousn"
  344. ".section __ex_table,"a"n"
  345. "   .align 8n"
  346. "   .quad  0b,3bn"
  347. "   .quad  1b,3bn"
  348. ".previous"
  349.                                 : "=&a" (len)
  350.                                 : "a"  (dst), "d" (src), "d" (count),
  351.                                   "K" (-EFAULT)
  352.                                 : "cc", "2" ,"3", "4" );
  353.         return len;
  354. }
  355. static inline long
  356. strncpy_from_user(char *dst, const char *src, long count)
  357. {
  358.         long res = -EFAULT;
  359.         if (access_ok(VERIFY_READ, src, 1))
  360.                 res = __strncpy_from_user(dst, src, count);
  361.         return res;
  362. }
  363. /*
  364.  * Return the size of a string (including the ending 0)
  365.  *
  366.  * Return 0 for error
  367.  */
  368. static inline unsigned long
  369. strnlen_user(const char * src, unsigned long n)
  370. {
  371. #if 0
  372.         __asm__ __volatile__ ("   algr  %0,%1n"
  373.                               "   slgr  0,0n"
  374.                               "   lgr   4,%1n"
  375.                               "   sacf  512n"
  376.                               "0: srst  %0,4n"
  377.                               "   jo    0bn"
  378.                               "   slgr  %0,%1n"
  379.                               "   aghi  %0,1n"
  380.                               "1: sacf  0n"
  381.                               ".section .fixup,"ax"n"
  382.                               "2: slgr  %0,%0n"
  383.                               "   jg    1bn"
  384.                               ".previousn"
  385.                               ".section __ex_table,"a"n"
  386.                               "   .align 8n"
  387.                               "   .quad  0b,2bn"
  388.                               ".previous"
  389.                               : "+&a" (n) : "d" (src)
  390.                               : "cc", "0", "4" );
  391. #else
  392. __asm__ __volatile__ ("   lgr   4,%1n"
  393.       "   sacf  512n"
  394.       "0: cli   0(4),0x00n"
  395.                               "   la    4,1(4)n"
  396.       "   je    1fn"
  397.                               "   brctg %0,0bn"
  398.       "1: lgr   %0,4n"
  399.       "   slgr  %0,%1n"
  400.       "2: sacf  0n"
  401.                               ".section .fixup,"ax"n"
  402.                               "3: slgr  %0,%0n"
  403.                               "   jg    2bn"  
  404.                               ".previousn"
  405.       ".section __ex_table,"a"n"
  406.       "   .align 8n"
  407.       "   .quad  0b,3bn"
  408.       ".previous"
  409.       : "+&a" (n) : "d" (src)
  410.       : "cc", "4" );
  411. #endif
  412.         return n;
  413. }
  414. #define strlen_user(str) strnlen_user(str, ~0UL)
  415. /*
  416.  * Zero Userspace
  417.  */
  418. extern long __clear_user_asm(void *to, long n);
  419. #define __clear_user(to, n)                                     
  420. ({                                                              
  421.         __clear_user_asm(to, n);                                
  422. })
  423. static inline unsigned long
  424. clear_user(void *to, unsigned long n)
  425. {
  426.         if (access_ok(VERIFY_WRITE, to, n))
  427.                 n = __clear_user(to, n);
  428.         return n;
  429. }
  430. #endif                                 /* _S390_UACCESS_H                  */