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

Linux/Unix编程

开发平台:

Unix_Linux

  1. #ifndef __X86_64_UACCESS_H
  2. #define __X86_64_UACCESS_H
  3. /*
  4.  * User space memory access functions
  5.  */
  6. #include <linux/config.h>
  7. #include <linux/errno.h>
  8. #include <linux/sched.h>
  9. #include <linux/prefetch.h>
  10. #include <asm/page.h>
  11. #define VERIFY_READ 0
  12. #define VERIFY_WRITE 1
  13. /*
  14.  * The fs value determines whether argument validity checking should be
  15.  * performed or not.  If get_fs() == USER_DS, checking is performed, with
  16.  * get_fs() == KERNEL_DS, checking is bypassed.
  17.  *
  18.  * For historical reasons, these macros are grossly misnamed.
  19.  */
  20. #define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
  21. #define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFFFFFFFFFF)
  22. #define USER_DS MAKE_MM_SEG(PAGE_OFFSET)
  23. #define get_ds() (KERNEL_DS)
  24. #define get_fs() (current->addr_limit)
  25. #define set_fs(x) (current->addr_limit = (x))
  26. #define segment_eq(a,b) ((a).seg == (b).seg)
  27. #define __addr_ok(addr) (!((unsigned long)(addr) & (current->addr_limit.seg)))
  28. /*
  29.  * Uhhuh, this needs 65-bit arithmetic. We have a carry..
  30.  */
  31. #define __range_not_ok(addr,size) ({ 
  32. unsigned long flag,sum; 
  33. asm("# range_oknr" 
  34. "addq %3,%1 ; sbbq %0,%0 ; cmpq %1,%4 ; sbbq $0,%0"  
  35. :"=&r" (flag), "=r" (sum) 
  36. :"1" (addr),"g" ((long)(size)),"g" (current->addr_limit.seg)); 
  37. flag; })
  38. #define access_ok(type,addr,size) (__range_not_ok(addr,size) == 0)
  39. extern inline int verify_area(int type, const void * addr, unsigned long size)
  40. {
  41. return access_ok(type,addr,size) ? 0 : -EFAULT;
  42. }
  43. /*
  44.  * The exception table consists of pairs of addresses: the first is the
  45.  * address of an instruction that is allowed to fault, and the second is
  46.  * the address at which the program should continue.  No registers are
  47.  * modified, so it is entirely up to the continuation code to figure out
  48.  * what to do.
  49.  *
  50.  * All the routines below use bits of fixup code that are out of line
  51.  * with the main instruction path.  This means when everything is well,
  52.  * we don't even have to jump over them.  Further, they do not intrude
  53.  * on our cache or tlb entries.
  54.  */
  55. struct exception_table_entry
  56. {
  57. unsigned long insn, fixup;
  58. };
  59. /* Returns 0 if exception not found and fixup otherwise.  */
  60. extern unsigned long search_exception_table(unsigned long);
  61. /*
  62.  * These are the main single-value transfer routines.  They automatically
  63.  * use the right size if we just have the right pointer type.
  64.  *
  65.  * This gets kind of ugly. We want to return _two_ values in "get_user()"
  66.  * and yet we don't want to do any pointers, because that is too much
  67.  * of a performance impact. Thus we have a few rather ugly macros here,
  68.  * and hide all the uglyness from the user.
  69.  *
  70.  * The "__xxx" versions of the user access functions are versions that
  71.  * do not verify the address space, that must have been done previously
  72.  * with a separate "access_ok()" call (this is used when we do multiple
  73.  * accesses to the same area of user memory).
  74.  */
  75. extern void __get_user_1(void);
  76. extern void __get_user_2(void);
  77. extern void __get_user_4(void);
  78. extern void __get_user_8(void);
  79. #define __get_user_x(size,ret,x,ptr) 
  80. __asm__ __volatile__("call __get_user_" #size 
  81. :"=a" (ret),"=d" (x) 
  82. :"0" (ptr) 
  83. :"rbx")
  84. /* Careful: we have to cast the result to the type of the pointer for sign reasons */
  85. #define get_user(x,ptr)
  86. ({ long __ret_gu,__val_gu;
  87. switch(sizeof (*(ptr))) {
  88. case 1:  __get_user_x(1,__ret_gu,__val_gu,ptr); break;
  89. case 2:  __get_user_x(2,__ret_gu,__val_gu,ptr); break;
  90. case 4:  __get_user_x(4,__ret_gu,__val_gu,ptr); break;
  91. case 8:  __get_user_x(8,__ret_gu,__val_gu,ptr); break;
  92. default: __get_user_bad(); break;
  93. }
  94. (x) = (__typeof__(*(ptr)))__val_gu;
  95. __ret_gu;
  96. })
  97. extern void __put_user_1(void);
  98. extern void __put_user_2(void);
  99. extern void __put_user_4(void);
  100. extern void __put_user_8(void);
  101. extern void __put_user_bad(void);
  102. #define __put_user_x(size,ret,x,ptr)
  103. __asm__ __volatile__("call __put_user_" #size
  104. :"=a" (ret)
  105. :"0" (ptr),"d" (x)
  106. :"rbx")
  107. #define put_user(x,ptr)
  108.   __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
  109. #define __get_user(x,ptr) 
  110.   __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
  111. #define __put_user(x,ptr) 
  112.   __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
  113. #define __put_user_nocheck(x,ptr,size)
  114. ({
  115. long __pu_err;
  116. __put_user_size((x),(ptr),(size),__pu_err);
  117. __pu_err;
  118. })
  119. #define __put_user_check(x,ptr,size)
  120. ({
  121. long __pu_err = -EFAULT;
  122. __typeof__(*(ptr)) *__pu_addr = (ptr);
  123. if (access_ok(VERIFY_WRITE,__pu_addr,size))
  124. __put_user_size((x),__pu_addr,(size),__pu_err);
  125. __pu_err;
  126. })
  127. #define __put_user_size(x,ptr,size,retval)
  128. do {
  129. retval = 0;
  130. switch (size) {
  131.   case 1: __put_user_asm(x,ptr,retval,"b","b","iq"); break;
  132.   case 2: __put_user_asm(x,ptr,retval,"w","w","ir"); break;
  133.   case 4: __put_user_asm(x,ptr,retval,"l","k","ir"); break;
  134.   case 8: __put_user_asm(x,ptr,retval,"q","","ir"); break;
  135.   default: __put_user_bad();
  136. }
  137. } while (0)
  138. /* FIXME: this hack is definitely wrong -AK */
  139. struct __large_struct { unsigned long buf[100]; };
  140. #define __m(x) (*(struct __large_struct *)(x))
  141. /*
  142.  * Tell gcc we read from memory instead of writing: this is because
  143.  * we do not write to any memory gcc knows about, so there are no
  144.  * aliasing issues.
  145.  */
  146. #define __put_user_asm(x, addr, err, itype, rtype, ltype)
  147. __asm__ __volatile__(
  148. "1: mov"itype" %"rtype"1,%2n"
  149. "2:n"
  150. ".section .fixup,"ax"n"
  151. "3: movq %3,%0n"
  152. " jmp 2bn"
  153. ".previousn"
  154. ".section __ex_table,"a"n"
  155. " .align 8n"
  156. " .quad 1b,3bn"
  157. ".previous"
  158. : "=r"(err)
  159. : ltype (x), "m"(__m(addr)), "i"(-EFAULT), "0"(err))
  160. #define __get_user_nocheck(x,ptr,size)
  161. ({
  162. long __gu_err, __gu_val;
  163. __get_user_size(__gu_val,(ptr),(size),__gu_err);
  164. (x) = (__typeof__(*(ptr)))__gu_val;
  165. __gu_err;
  166. })
  167. extern long __get_user_bad(void);
  168. #define __get_user_size(x,ptr,size,retval)
  169. do {
  170. retval = 0;
  171. switch (size) {
  172.   case 1: __get_user_asm(x,ptr,retval,"b","b","=q"); break;
  173.   case 2: __get_user_asm(x,ptr,retval,"w","w","=r"); break;
  174.   case 4: __get_user_asm(x,ptr,retval,"l","k","=r"); break;
  175.   case 8: __get_user_asm(x,ptr,retval,"q","","=r"); break;
  176.   default: (x) = __get_user_bad();
  177. }
  178. } while (0)
  179. #define __get_user_asm(x, addr, err, itype, rtype, ltype)
  180. __asm__ __volatile__(
  181. "1: mov"itype" %2,%"rtype"1n"
  182. "2:n"
  183. ".section .fixup,"ax"n"
  184. "3: mov %3,%0n"
  185. " xor"itype" %"rtype"1,%"rtype"1n"
  186. " jmp 2bn"
  187. ".previousn"
  188. ".section __ex_table,"a"n"
  189. " .align 8n"
  190. " .quad 1b,3bn"
  191. ".previous"
  192. : "=r"(err), ltype (x)
  193. : "m"(__m(addr)), "i"(-EFAULT), "0"(err))
  194. /*
  195.  * Copy To/From Userspace
  196.  * 
  197.  * This relies on an optimized common worker function.
  198.  * 
  199.  * Could do special inline versions for small constant copies, but avoid this
  200.  * for now. It's not clear it is worth it. 
  201.  */
  202. extern unsigned long copy_user_generic(void *to, const void *from, unsigned len); 
  203. extern unsigned long copy_to_user(void *to, const void *from, unsigned len); 
  204. extern unsigned long copy_from_user(void *to, const void *from, unsigned len); 
  205. #define __copy_to_user copy_user_generic
  206. #define __copy_from_user copy_user_generic
  207. long strncpy_from_user(char *dst, const char *src, long count);
  208. long __strncpy_from_user(char *dst, const char *src, long count);
  209. #define strlen_user(str) strnlen_user(str, ~0UL >> 1)
  210. long strnlen_user(const char *str, long n);
  211. unsigned long clear_user(void *mem, unsigned long len);
  212. unsigned long __clear_user(void *mem, unsigned long len);
  213. #endif /* __X86_64_UACCESS_H */