uaccess.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:21k
源码类别:

嵌入式Linux

开发平台:

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.         int __pu_err;                                           
  153.         switch (sizeof (*(ptr))) {                              
  154.                 case 1:                                         
  155.                         __pu_err = __put_user_asm_1((__u8)(__u64)(x),(ptr));
  156.                         break;                                  
  157.                 case 2:                                         
  158.                         __pu_err = __put_user_asm_2((__u16)(__u64)(x),(ptr));
  159.                         break;                                  
  160.                 case 4:                                         
  161.                         __pu_err = __put_user_asm_4((__u32)(__u64)(x),(ptr));
  162.                         break;                                  
  163.                 case 8:                                         
  164.                         __pu_err = __put_user_asm_8((__u64)(x),(ptr));
  165.                         break;                                  
  166.                 default:                                        
  167.                 __pu_err = __put_user_bad();                    
  168.                 break;                                          
  169.          }                                                      
  170.         __pu_err;                                               
  171. })
  172. #define put_user(x, ptr)                                        
  173. ({                                                              
  174.         long __pu_err = -EFAULT;                                
  175.         __typeof__(*(ptr)) *__pu_addr = (ptr);                  
  176.         __typeof__(*(ptr)) __x = (x);                           
  177.         if (__access_ok((long)__pu_addr,sizeof(*(ptr)))) {      
  178.                 __pu_err = 0;                                   
  179.                 __put_user((__x), (__pu_addr));                 
  180.         }                                                       
  181.         __pu_err;                                               
  182. })
  183. extern int __put_user_bad(void);
  184. #define __get_user_asm_8(x, ptr, err)                                      
  185. ({                                                                         
  186.         __asm__ __volatile__ (  "   sr    %1,%1n"                         
  187.                                 "   la    4,%2n"                          
  188.                                 "   sacf  512n"                           
  189.                                 "0: lg    %0,0(4)n"                       
  190.                                 "1: sacf  0n"                             
  191.                                 ".section .fixup,"ax"n"                 
  192.                                 "2: lhi   %1,%h3n"                        
  193.                                 "   jg    1bn"                            
  194.                                 ".previousn"                              
  195.                                 ".section __ex_table,"a"n"              
  196.                                 "   .align 8n"                            
  197.                                 "   .quad 0b,2bn"                         
  198.                                 ".previous"                                
  199.                                 : "=d" (x) , "=&d" (err)                   
  200.                                 : "m" (*(const __u64*)(ptr)),"K" (-EFAULT) 
  201.                                 : "cc", "4" );                             
  202. })
  203. #define __get_user_asm_4(x, ptr, err)                                      
  204. ({                                                                         
  205.         __asm__ __volatile__ (  "   sr    %1,%1n"                         
  206.                                 "   la    4,%2n"                          
  207.                                 "   sacf  512n"                           
  208.                                 "0: l     %0,0(4)n"                       
  209.                                 "1: sacf  0n"                             
  210.                                 ".section .fixup,"ax"n"                 
  211.                                 "2: lhi   %1,%h3n"                        
  212.                                 "   jg    1bn"                            
  213.                                 ".previousn"                              
  214.                                 ".section __ex_table,"a"n"              
  215.                                 "   .align 8n"                            
  216.                                 "   .quad 0b,2bn"                         
  217.                                 ".previous"                                
  218.                                 : "=d" (x) , "=&d" (err)                   
  219.                                 : "m" (*(const __u32*)(ptr)),"K" (-EFAULT) 
  220.                                 : "cc", "4" );                             
  221. })
  222. #define __get_user_asm_2(x, ptr, err)                                      
  223. ({                                                                         
  224.         __asm__ __volatile__ (  "   sr    %1,%1n"                         
  225.                                 "   la    4,%2n"                          
  226.                                 "   sacf  512n"                           
  227.                                 "0: lh    %0,0(4)n"                       
  228.                                 "1: sacf  0n"                             
  229.                                 ".section .fixup,"ax"n"                 
  230.                                 "2: lhi   %1,%h3n"                        
  231.                                 "   jg    1bn"                            
  232.                                 ".previousn"                              
  233.                                 ".section __ex_table,"a"n"              
  234.                                 "   .align 8n"                            
  235.                                 "   .quad 0b,2bn"                         
  236.                                 ".previous"                                
  237.                                 : "=d" (x) , "=&d" (err)                   
  238.                                 : "m" (*(const __u16*)(ptr)),"K" (-EFAULT) 
  239.                                 : "cc", "4" );                             
  240. })
  241. #define __get_user_asm_1(x, ptr, err)                                     
  242. ({                                                                        
  243.         __asm__ __volatile__ (  "   sr    %1,%1n"                        
  244.                                 "   la    4,%2n"                         
  245.                                 "   sr    %0,%0n"                        
  246.                                 "   sacf  512n"                          
  247.                                 "0: ic    %0,0(4)n"                      
  248.                                 "1: sacf  0n"                            
  249.                                 ".section .fixup,"ax"n"                
  250.                                 "2: lhi   %1,%h3n"                       
  251.                                 "   jg    1bn"                           
  252.                                 ".previousn"                             
  253.                                 ".section __ex_table,"a"n"             
  254.                                 "   .align 8n"                           
  255.                                 "   .quad 0b,2bn"                        
  256.                                 ".previous"                               
  257.                                 : "=d" (x) , "=&d" (err)                  
  258.                                 : "m" (*(const __u8*)(ptr)),"K" (-EFAULT) 
  259.                                 : "cc", "4" );                            
  260. })
  261. #define __get_user(x, ptr)                                      
  262. ({                                                              
  263.         int __gu_err;                                           
  264.         switch (sizeof(*(ptr))) {                               
  265.                 case 1:                                         
  266.                         __get_user_asm_1(x,ptr,__gu_err);       
  267.                         break;                                  
  268.                 case 2:                                         
  269.                         __get_user_asm_2(x,ptr,__gu_err);       
  270.                         break;                                  
  271.                 case 4:                                         
  272.                         __get_user_asm_4(x,ptr,__gu_err);       
  273.                         break;                                  
  274.                 case 8:                                         
  275.                         __get_user_asm_8(x,ptr,__gu_err);       
  276.                         break;                                  
  277.                 default:                                        
  278.                         (x) = 0;                                
  279.                         __gu_err = __get_user_bad();            
  280.                 break;                                          
  281.         }                                                       
  282.         __gu_err;                                               
  283. })
  284. #define get_user(x, ptr)                                        
  285. ({                                                              
  286.         long __gu_err = -EFAULT;                                
  287.         __typeof__(ptr) __gu_addr = (ptr);                      
  288.         __typeof__(*(ptr)) __x;                                 
  289.         if (__access_ok((long)__gu_addr,sizeof(*(ptr)))) {      
  290.                 __gu_err = 0;                                   
  291.                 __get_user((__x), (__gu_addr));                 
  292.                 (x) = __x;                                      
  293.         }                                                       
  294.         else                                                    
  295.                 (x) = 0;                                        
  296.         __gu_err;                                               
  297. })
  298. extern int __get_user_bad(void);
  299. /*
  300.  * access register are set up, that 4 points to secondary (user) , 2 to primary (kernel)
  301.  */
  302. extern long __copy_to_user_asm(const void *from, long n, void *to);
  303. #define __copy_to_user(to, from, n)                             
  304. ({                                                              
  305.         __copy_to_user_asm(from, n, to);                        
  306. })
  307. #define copy_to_user(to, from, n)                               
  308. ({                                                              
  309.         long err = 0;                                           
  310.         __typeof__(n) __n = (n);                                
  311.         if (__access_ok(to,__n)) {                              
  312.                 err = __copy_to_user_asm(from, __n, to);        
  313.         }                                                       
  314.         else                                                    
  315.                 err = __n;                                      
  316.         err;                                                    
  317. })
  318. extern long __copy_from_user_asm(void *to, long n, const void *from);
  319. #define __copy_from_user(to, from, n)                           
  320. ({                                                              
  321.         __copy_from_user_asm(to, n, from);                      
  322. })
  323. #define copy_from_user(to, from, n)                             
  324. ({                                                              
  325.         long err = 0;                                           
  326.         __typeof__(n) __n = (n);                                
  327.         if (__access_ok(from,__n)) {                            
  328.                 err = __copy_from_user_asm(to, __n, from);      
  329.         }                                                       
  330.         else                                                    
  331.                 err = __n;                                      
  332.         err;                                                    
  333. })
  334. /*
  335.  * Copy a null terminated string from userspace.
  336.  */
  337. static inline long
  338. __strncpy_from_user(char *dst, const char *src, long count)
  339. {
  340.         long len;
  341.         __asm__ __volatile__ (  "   slgr  %0,%0n"
  342. "   lgr   2,%1n"
  343.                                 "   lgr   4,%2n"
  344.                                 "   slr   3,3n"
  345.                                 "   sacf  512n"
  346.                                 "0: ic    3,0(%0,4)n"
  347.                                 "1: stc   3,0(%0,2)n"
  348.                                 "   ltr   3,3n"
  349.                                 "   jz    2fn"
  350.                                 "   aghi  %0,1n"
  351.                                 "   cgr   %0,%3n"
  352.                                 "   jl    0bn"
  353.                                 "2: sacf  0n"
  354. ".section .fixup,"ax"n"
  355. "3: lghi  %0,%h4n"
  356. "   jg    2bn"  
  357. ".previousn"
  358. ".section __ex_table,"a"n"
  359. "   .align 8n"
  360. "   .quad  0b,3bn"
  361. "   .quad  1b,3bn"
  362. ".previous"
  363.                                 : "=&a" (len)
  364.                                 : "a"  (dst), "d" (src), "d" (count),
  365.                                   "K" (-EFAULT)
  366.                                 : "cc", "2" ,"3", "4" );
  367.         return len;
  368. }
  369. static inline long
  370. strncpy_from_user(char *dst, const char *src, long count)
  371. {
  372.         long res = -EFAULT;
  373.         if (access_ok(VERIFY_READ, src, 1))
  374.                 res = __strncpy_from_user(dst, src, count);
  375.         return res;
  376. }
  377. /*
  378.  * Return the size of a string (including the ending 0)
  379.  *
  380.  * Return 0 for error
  381.  */
  382. static inline unsigned long
  383. strnlen_user(const char * src, unsigned long n)
  384. {
  385. #if 0
  386.         __asm__ __volatile__ ("   algr  %0,%1n"
  387.                               "   slgr  0,0n"
  388.                               "   lgr   4,%1n"
  389.                               "   sacf  512n"
  390.                               "0: srst  %0,4n"
  391.                               "   jo    0bn"
  392.                               "   slgr  %0,%1n"
  393.                               "   aghi  %0,1n"
  394.                               "1: sacf  0n"
  395.                               ".section .fixup,"ax"n"
  396.                               "2: slgr  %0,%0n"
  397.                               "   jg    1bn"
  398.                               ".previousn"
  399.                               ".section __ex_table,"a"n"
  400.                               "   .align 8n"
  401.                               "   .quad  0b,2bn"
  402.                               ".previous"
  403.                               : "+&a" (n) : "d" (src)
  404.                               : "cc", "0", "4" );
  405. #else
  406. __asm__ __volatile__ ("   lgr   4,%1n"
  407.       "   sacf  512n"
  408.       "0: cli   0(4),0x00n"
  409.                               "   la    4,1(4)n"
  410.       "   je    1fn"
  411.                               "   brctg %0,0bn"
  412.       "1: lgr   %0,4n"
  413.       "   slgr  %0,%1n"
  414.       "2: sacf  0n"
  415.                               ".section .fixup,"ax"n"
  416.                               "3: slgr  %0,%0n"
  417.                               "   jg    2bn"  
  418.                               ".previousn"
  419.       ".section __ex_table,"a"n"
  420.       "   .align 8n"
  421.       "   .quad  0b,3bn"
  422.       ".previous"
  423.       : "+&a" (n) : "d" (src)
  424.       : "cc", "4" );
  425. #endif
  426.         return n;
  427. }
  428. #define strlen_user(str) strnlen_user(str, ~0UL)
  429. /*
  430.  * Zero Userspace
  431.  */
  432. extern long __clear_user_asm(void *to, long n);
  433. #define __clear_user(to, n)                                     
  434. ({                                                              
  435.         __clear_user_asm(to, n);                                
  436. })
  437. static inline unsigned long
  438. clear_user(void *to, unsigned long n)
  439. {
  440.         if (access_ok(VERIFY_WRITE, to, n))
  441.                 n = __clear_user(to, n);
  442.         return n;
  443. }
  444. #endif                                 /* _S390_UACCESS_H                  */