basicAlgorithmEncapsulation.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. #ifndef __ALPHA_UACCESS_H
  2. #define __ALPHA_UACCESS_H
  3. #include <linux/errno.h>
  4. #include <linux/sched.h>
  5. /*
  6. * The fs value determines whether argument validity checking should be
  7. * performed or not. If get_fs() == USER_DS, checking is performed, with
  8. * get_fs() == KERNEL_DS, checking is bypassed.
  9. *
  10. * Or at least it did once upon a time. Nowadays it is a mask that
  11. * defines which bits of the address space are off limits. This is a
  12. * wee bit faster than the above.
  13. *
  14. * For historical reasons, these macros are grossly misnamed.
  15. */
  16. #define KERNEL_DS ((mm_segment_t) { 0UL })
  17. #define USER_DS ((mm_segment_t) { -0x40000000000UL })
  18. #define VERIFY_READ 0
  19. #define VERIFY_WRITE 1
  20. #define get_fs() (current_thread_info()->addr_limit)
  21. #define get_ds() (KERNEL_DS)
  22. #define set_fs(x) (current_thread_info()->addr_limit = (x))
  23. #define segment_eq(a,b) ((a).seg == (b).seg)
  24. /*
  25. * Is a address valid? This does a straightforward calculation rather
  26. * than tests.
  27. *
  28. * Address valid if:
  29. * - "addr" doesn't have any high-bits set
  30. * - AND "size" doesn't have any high-bits set
  31. * - AND "addr+size" doesn't have any high-bits set
  32. * - OR we are in kernel mode.
  33. */
  34. #define __access_ok(addr,size,segment) \
  35. (((segment).seg & (addr | size | (addr+size))) == 0)
  36. #define access_ok(type,addr,size) \
  37. ({ \
  38. __chk_user_ptr(addr); \
  39. __access_ok(((unsigned long)(addr)),(size),get_fs()); \
  40. })
  41. /*
  42. * These are the main single-value transfer routines. They automatically
  43. * use the right size if we just have the right pointer type.
  44. *
  45. * As the alpha uses the same address space for kernel and user
  46. * data, we can just do these as direct assignments. (Of course, the
  47. * exception handling means that it's no longer "just"...)
  48. *
  49. * Careful to not
  50. * (a) re-use the arguments for side effects (sizeof/typeof is ok)
  51. * (b) require any knowledge of processes at this stage
  52. */
  53. #define put_user(x,ptr) \
  54. __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)),get_fs())
  55. #define get_user(x,ptr) \
  56. __get_user_check((x),(ptr),sizeof(*(ptr)),get_fs())
  57. /*
  58. * The "__xxx" versions do not do address space checking, useful when
  59. * doing multiple accesses to the same area (the programmer has to do the
  60. * checks by hand with "access_ok()")
  61. */
  62. #define __put_user(x,ptr) \
  63. __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
  64. #define __get_user(x,ptr) \
  65. __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
  66. /*
  67. * The "lda %1, 2b-1b(%0)" bits are magic to get the assembler to
  68. * encode the bits we need for resolving the exception. See the
  69. * more extensive comments with fixup_inline_exception below for
  70. * more information.
  71. */
  72. extern void __get_user_unknown(void);
  73. #define __get_user_nocheck(x,ptr,size) \
  74. ({ \
  75. long __gu_err = 0; \
  76. unsigned long __gu_val; \
  77. __chk_user_ptr(ptr); \
  78. switch (size) { \
  79. case 1: __get_user_8(ptr); break; \
  80. case 2: __get_user_16(ptr); break; \
  81. case 4: __get_user_32(ptr); break; \
  82. case 8: __get_user_64(ptr); break; \
  83. default: __get_user_unknown(); break; \
  84. } \
  85. (x) = (__typeof__(*(ptr))) __gu_val; \
  86. __gu_err; \
  87. })
  88. #define __get_user_check(x,ptr,size,segment) \
  89. ({ \
  90. long __gu_err = -EFAULT; \
  91. unsigned long __gu_val = 0; \
  92. const __typeof__(*(ptr)) __user *__gu_addr = (ptr); \
  93. if (__access_ok((unsigned long)__gu_addr,size,segment)) { \
  94. __gu_err = 0; \
  95. switch (size) { \
  96. case 1: __get_user_8(__gu_addr); break; \
  97. case 2: __get_user_16(__gu_addr); break; \
  98. case 4: __get_user_32(__gu_addr); break; \
  99. case 8: __get_user_64(__gu_addr); break; \
  100. default: __get_user_unknown(); break; \
  101. } \
  102. } \
  103. (x) = (__typeof__(*(ptr))) __gu_val; \
  104. __gu_err; \
  105. })
  106. struct __large_struct { unsigned long buf[100]; };
  107. #define __m(x) (*(struct __large_struct __user *)(x))
  108. #define __get_user_64(addr) \
  109. __asm__("1: ldq %0,%2\n" \
  110. "2:\n" \
  111. ".section __ex_table,\"a\"\n" \
  112. " .long 1b - .\n" \
  113. " lda %0, 2b-1b(%1)\n" \
  114. ".previous" \
  115. : "=r"(__gu_val), "=r"(__gu_err) \
  116. : "m"(__m(addr)), "1"(__gu_err))
  117. #define __get_user_32(addr) \
  118. __asm__("1: ldl %0,%2\n" \
  119. "2:\n" \
  120. ".section __ex_table,\"a\"\n" \
  121. " .long 1b - .\n" \
  122. " lda %0, 2b-1b(%1)\n" \
  123. ".previous" \
  124. : "=r"(__gu_val), "=r"(__gu_err) \
  125. : "m"(__m(addr)), "1"(__gu_err))
  126. #ifdef __alpha_bwx__
  127. /* Those lucky bastards with ev56 and later CPUs can do byte/word moves. */
  128. #define __get_user_16(addr) \
  129. __asm__("1: ldwu %0,%2\n" \
  130. "2:\n" \
  131. ".section __ex_table,\"a\"\n" \
  132. " .long 1b - .\n" \
  133. " lda %0, 2b-1b(%1)\n" \
  134. ".previous" \
  135. : "=r"(__gu_val), "=r"(__gu_err) \
  136. : "m"(__m(addr)), "1"(__gu_err))
  137. #define __get_user_8(addr) \
  138. __asm__("1: ldbu %0,%2\n" \
  139. "2:\n" \
  140. ".section __ex_table,\"a\"\n" \
  141. " .long 1b - .\n" \
  142. " lda %0, 2b-1b(%1)\n" \
  143. ".previous" \
  144. : "=r"(__gu_val), "=r"(__gu_err) \
  145. : "m"(__m(addr)), "1"(__gu_err))
  146. #else
  147. /* Unfortunately, we can't get an unaligned access trap for the sub-word
  148. load, so we have to do a general unaligned operation. */
  149. #define __get_user_16(addr) \
  150. { \
  151. long __gu_tmp; \
  152. __asm__("1: ldq_u %0,0(%3)\n" \
  153. "2: ldq_u %1,1(%3)\n" \
  154. " extwl %0,%3,%0\n" \
  155. " extwh %1,%3,%1\n" \
  156. " or %0,%1,%0\n" \
  157. "3:\n" \
  158. ".section __ex_table,\"a\"\n" \
  159. " .long 1b - .\n" \
  160. " lda %0, 3b-1b(%2)\n" \
  161. " .long 2b - .\n" \
  162. " lda %0, 3b-2b(%2)\n" \
  163. ".previous" \
  164. : "=&r"(__gu_val), "=&r"(__gu_tmp), "=r"(__gu_err) \
  165. : "r"(addr), "2"(__gu_err)); \
  166. }
  167. #define __get_user_8(addr) \
  168. __asm__("1: ldq_u %0,0(%2)\n" \
  169. " extbl %0,%2,%0\n" \
  170. "2:\n" \
  171. ".section __ex_table,\"a\"\n" \
  172. " .long 1b - .\n" \
  173. " lda %0, 2b-1b(%1)\n" \
  174. ".previous" \
  175. : "=&r"(__gu_val), "=r"(__gu_err) \
  176. : "r"(addr), "1"(__gu_err))
  177. #endif
  178. extern void __put_user_unknown(void);
  179. #define __put_user_nocheck(x,ptr,size) \
  180. ({ \
  181. long __pu_err = 0; \
  182. __chk_user_ptr(ptr); \
  183. switch (size) { \
  184. case 1: __put_user_8(x,ptr); break; \
  185. case 2: __put_user_16(x,ptr); break; \
  186. case 4: __put_user_32(x,ptr); break; \
  187. case 8: __put_user_64(x,ptr); break; \
  188. default: __put_user_unknown(); break; \
  189. } \
  190. __pu_err; \
  191. })
  192. #define __put_user_check(x,ptr,size,segment) \
  193. ({ \
  194. long __pu_err = -EFAULT; \
  195. __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
  196. if (__access_ok((unsigned long)__pu_addr,size,segment)) { \
  197. __pu_err = 0; \
  198. switch (size) { \
  199. case 1: __put_user_8(x,__pu_addr); break; \
  200. case 2: __put_user_16(x,__pu_addr); break; \
  201. case 4: __put_user_32(x,__pu_addr); break; \
  202. case 8: __put_user_64(x,__pu_addr); break; \
  203. default: __put_user_unknown(); break; \
  204. } \
  205. } \
  206. __pu_err; \
  207. })
  208. /*
  209. * The "__put_user_xx()" macros tell gcc they read from memory
  210. * instead of writing: this is because they do not write to
  211. * any memory gcc knows about, so there are no aliasing issues
  212. */
  213. #define __put_user_64(x,addr) \
  214. __asm__ __volatile__("1: stq %r2,%1\n" \
  215. "2:\n" \
  216. ".section __ex_table,\"a\"\n" \
  217. " .long 1b - .\n" \
  218. " lda $31,2b-1b(%0)\n" \
  219. ".previous" \
  220. : "=r"(__pu_err) \
  221. : "m" (__m(addr)), "rJ" (x), "0"(__pu_err))
  222. #define __put_user_32(x,addr) \
  223. __asm__ __volatile__("1: stl %r2,%1\n" \
  224. "2:\n" \
  225. ".section __ex_table,\"a\"\n" \
  226. " .long 1b - .\n" \
  227. " lda $31,2b-1b(%0)\n" \
  228. ".previous" \
  229. : "=r"(__pu_err) \
  230. : "m"(__m(addr)), "rJ"(x), "0"(__pu_err))
  231. #ifdef __alpha_bwx__
  232. /* Those lucky bastards with ev56 and later CPUs can do byte/word moves. */
  233. #define __put_user_16(x,addr) \
  234. __asm__ __volatile__("1: stw %r2,%1\n" \
  235. "2:\n" \
  236. ".section __ex_table,\"a\"\n" \
  237. " .long 1b - .\n" \
  238. " lda $31,2b-1b(%0)\n" \
  239. ".previous" \
  240. : "=r"(__pu_err) \
  241. : "m"(__m(addr)), "rJ"(x), "0"(__pu_err))
  242. #define __put_user_8(x,addr) \
  243. __asm__ __volatile__("1: stb %r2,%1\n" \
  244. "2:\n" \
  245. ".section __ex_table,\"a\"\n" \
  246. " .long 1b - .\n" \
  247. " lda $31,2b-1b(%0)\n" \
  248. ".previous" \
  249. : "=r"(__pu_err) \
  250. : "m"(__m(addr)), "rJ"(x), "0"(__pu_err))
  251. #else
  252. /* Unfortunately, we can't get an unaligned access trap for the sub-word
  253. write, so we have to do a general unaligned operation. */
  254. #define __put_user_16(x,addr) \
  255. { \
  256. long __pu_tmp1, __pu_tmp2, __pu_tmp3, __pu_tmp4; \
  257. __asm__ __volatile__( \
  258. "1: ldq_u %2,1(%5)\n" \
  259. "2: ldq_u %1,0(%5)\n" \
  260. " inswh %6,%5,%4\n" \
  261. " inswl %6,%5,%3\n" \
  262. " mskwh %2,%5,%2\n" \
  263. " mskwl %1,%5,%1\n" \
  264. " or %2,%4,%2\n" \
  265. " or %1,%3,%1\n" \
  266. "3: stq_u %2,1(%5)\n" \
  267. "4: stq_u %1,0(%5)\n" \
  268. "5:\n" \
  269. ".section __ex_table,\"a\"\n" \
  270. " .long 1b - .\n" \