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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* 
  2.  * User address space access functions.
  3.  * The non inlined parts of asm-i386/uaccess.h are here.
  4.  *
  5.  * Copyright 1997 Andi Kleen <ak@muc.de>
  6.  * Copyright 1997 Linus Torvalds
  7.  */
  8. #include <linux/config.h>
  9. #include <asm/uaccess.h>
  10. #include <asm/mmx.h>
  11. #ifdef CONFIG_X86_USE_3DNOW_AND_WORKS
  12. unsigned long
  13. __generic_copy_to_user(void *to, const void *from, unsigned long n)
  14. {
  15. if (access_ok(VERIFY_WRITE, to, n))
  16. {
  17. if(n<512)
  18. __copy_user(to,from,n);
  19. else
  20. mmx_copy_user(to,from,n);
  21. }
  22. return n;
  23. }
  24. unsigned long
  25. __generic_copy_from_user(void *to, const void *from, unsigned long n)
  26. {
  27. if (access_ok(VERIFY_READ, from, n))
  28. {
  29. if(n<512)
  30. __copy_user_zeroing(to,from,n);
  31. else
  32. mmx_copy_user_zeroing(to, from, n);
  33. }
  34. else
  35. memset(to, 0, n);
  36. return n;
  37. }
  38. #else
  39. unsigned long
  40. __generic_copy_to_user(void *to, const void *from, unsigned long n)
  41. {
  42. prefetch(from);
  43. if (access_ok(VERIFY_WRITE, to, n))
  44. __copy_user(to,from,n);
  45. return n;
  46. }
  47. unsigned long
  48. __generic_copy_from_user(void *to, const void *from, unsigned long n)
  49. {
  50. prefetchw(to);
  51. if (access_ok(VERIFY_READ, from, n))
  52. __copy_user_zeroing(to,from,n);
  53. else
  54. memset(to, 0, n);
  55. return n;
  56. }
  57. #endif
  58. /*
  59.  * Copy a null terminated string from userspace.
  60.  */
  61. #define __do_strncpy_from_user(dst,src,count,res)    
  62. do {    
  63. int __d0, __d1, __d2;    
  64. __asm__ __volatile__(    
  65. " testl %1,%1n"    
  66. " jz 2fn"    
  67. "0: lodsbn"    
  68. " stosbn"    
  69. " testb %%al,%%aln"    
  70. " jz 1fn"    
  71. " decl %1n"    
  72. " jnz 0bn"    
  73. "1: subl %1,%0n"    
  74. "2:n"    
  75. ".section .fixup,"ax"n"    
  76. "3: movl %5,%0n"    
  77. " jmp 2bn"    
  78. ".previousn"    
  79. ".section __ex_table,"a"n"    
  80. " .align 4n"    
  81. " .long 0b,3bn"    
  82. ".previous"    
  83. : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),    
  84.   "=&D" (__d2)    
  85. : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) 
  86. : "memory");    
  87. } while (0)
  88. long
  89. __strncpy_from_user(char *dst, const char *src, long count)
  90. {
  91. long res;
  92. __do_strncpy_from_user(dst, src, count, res);
  93. return res;
  94. }
  95. long
  96. strncpy_from_user(char *dst, const char *src, long count)
  97. {
  98. long res = -EFAULT;
  99. if (access_ok(VERIFY_READ, src, 1))
  100. __do_strncpy_from_user(dst, src, count, res);
  101. return res;
  102. }
  103. /*
  104.  * Zero Userspace
  105.  */
  106. #define __do_clear_user(addr,size)
  107. do {
  108. int __d0;
  109.    __asm__ __volatile__(
  110. "0: rep; stosln"
  111. " movl %2,%0n"
  112. "1: rep; stosbn"
  113. "2:n"
  114. ".section .fixup,"ax"n"
  115. "3: lea 0(%2,%0,4),%0n"
  116. " jmp 2bn"
  117. ".previousn"
  118. ".section __ex_table,"a"n"
  119. " .align 4n"
  120. " .long 0b,3bn"
  121. " .long 1b,2bn"
  122. ".previous"
  123. : "=&c"(size), "=&D" (__d0)
  124. : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0));
  125. } while (0)
  126. unsigned long
  127. clear_user(void *to, unsigned long n)
  128. {
  129. if (access_ok(VERIFY_WRITE, to, n))
  130. __do_clear_user(to, n);
  131. return n;
  132. }
  133. unsigned long
  134. __clear_user(void *to, unsigned long n)
  135. {
  136. __do_clear_user(to, n);
  137. return n;
  138. }
  139. /*
  140.  * Return the size of a string (including the ending 0)
  141.  *
  142.  * Return 0 on exception, a value greater than N if too long
  143.  */
  144. long strnlen_user(const char *s, long n)
  145. {
  146. unsigned long mask = -__addr_ok(s);
  147. unsigned long res, tmp;
  148. __asm__ __volatile__(
  149. " testl %0, %0n"
  150. " jz 3fn"
  151. " andl %0,%%ecxn"
  152. "0: repne; scasbn"
  153. " setne %%aln"
  154. " subl %%ecx,%0n"
  155. " addl %0,%%eaxn"
  156. "1:n"
  157. ".section .fixup,"ax"n"
  158. "2: xorl %%eax,%%eaxn"
  159. " jmp 1bn"
  160. "3: movb $1,%%aln"
  161. " jmp 1bn"
  162. ".previousn"
  163. ".section __ex_table,"a"n"
  164. " .align 4n"
  165. " .long 0b,2bn"
  166. ".previous"
  167. :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
  168. :"0" (n), "1" (s), "2" (0), "3" (mask)
  169. :"cc");
  170. return res & mask;
  171. }