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

Linux/Unix编程

开发平台:

Unix_Linux

  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.fs)
  21. #define get_ds()  (KERNEL_DS)
  22. #define set_fs(x) (current->thread.fs = (x))
  23. #define segment_eq(a,b) ((a).seg == (b).seg)
  24. /*
  25.  * Is a address valid? This does a straighforward 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. __access_ok(((unsigned long)(addr)),(size),get_fs())
  38. extern inline int verify_area(int type, const void * addr, unsigned long size)
  39. {
  40. return access_ok(type,addr,size) ? 0 : -EFAULT;
  41. }
  42. /*
  43.  * These are the main single-value transfer routines.  They automatically
  44.  * use the right size if we just have the right pointer type.
  45.  *
  46.  * As the alpha uses the same address space for kernel and user
  47.  * data, we can just do these as direct assignments.  (Of course, the
  48.  * exception handling means that it's no longer "just"...)
  49.  *
  50.  * Careful to not
  51.  * (a) re-use the arguments for side effects (sizeof/typeof is ok)
  52.  * (b) require any knowledge of processes at this stage
  53.  */
  54. #define put_user(x,ptr) 
  55.   __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)),get_fs())
  56. #define get_user(x,ptr) 
  57.   __get_user_check((x),(ptr),sizeof(*(ptr)),get_fs())
  58. /*
  59.  * The "__xxx" versions do not do address space checking, useful when
  60.  * doing multiple accesses to the same area (the programmer has to do the
  61.  * checks by hand with "access_ok()")
  62.  */
  63. #define __put_user(x,ptr) 
  64.   __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
  65. #define __get_user(x,ptr) 
  66.   __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
  67.   
  68. /*
  69.  * The "lda %1, 2b-1b(%0)" bits are magic to get the assembler to
  70.  * encode the bits we need for resolving the exception.  See the
  71.  * more extensive comments with fixup_inline_exception below for
  72.  * more information.
  73.  */
  74. extern void __get_user_unknown(void);
  75. #define __get_user_nocheck(x,ptr,size)
  76. ({
  77. long __gu_err = 0, __gu_val;
  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, __gu_val = 0;
  91. const __typeof__(*(ptr)) *__gu_addr = (ptr);
  92. if (__access_ok((long)__gu_addr,size,segment)) {
  93. __gu_err = 0;
  94. switch (size) {
  95.   case 1: __get_user_8(__gu_addr); break;
  96.   case 2: __get_user_16(__gu_addr); break;
  97.   case 4: __get_user_32(__gu_addr); break;
  98.   case 8: __get_user_64(__gu_addr); break;
  99.   default: __get_user_unknown(); break;
  100. }
  101. }
  102. (x) = (__typeof__(*(ptr))) __gu_val;
  103. __gu_err;
  104. })
  105. struct __large_struct { unsigned long buf[100]; };
  106. #define __m(x) (*(struct __large_struct *)(x))
  107. #define __get_user_64(addr)
  108. __asm__("1: ldq %0,%2n"
  109. "2:n"
  110. ".section __ex_table,"a"n"
  111. " .gprel32 1bn"
  112. " lda %0, 2b-1b(%1)n"
  113. ".previous"
  114. : "=r"(__gu_val), "=r"(__gu_err)
  115. : "m"(__m(addr)), "1"(__gu_err))
  116. #define __get_user_32(addr)
  117. __asm__("1: ldl %0,%2n"
  118. "2:n"
  119. ".section __ex_table,"a"n"
  120. " .gprel32 1bn"
  121. " lda %0, 2b-1b(%1)n"
  122. ".previous"
  123. : "=r"(__gu_val), "=r"(__gu_err)
  124. : "m"(__m(addr)), "1"(__gu_err))
  125. #ifdef __alpha_bwx__
  126. /* Those lucky bastards with ev56 and later CPUs can do byte/word moves.  */
  127. #define __get_user_16(addr)
  128. __asm__("1: ldwu %0,%2n"
  129. "2:n"
  130. ".section __ex_table,"a"n"
  131. " .gprel32 1bn"
  132. " lda %0, 2b-1b(%1)n"
  133. ".previous"
  134. : "=r"(__gu_val), "=r"(__gu_err)
  135. : "m"(__m(addr)), "1"(__gu_err))
  136. #define __get_user_8(addr)
  137. __asm__("1: ldbu %0,%2n"
  138. "2:n"
  139. ".section __ex_table,"a"n"
  140. " .gprel32 1bn"
  141. " lda %0, 2b-1b(%1)n"
  142. ".previous"
  143. : "=r"(__gu_val), "=r"(__gu_err)
  144. : "m"(__m(addr)), "1"(__gu_err))
  145. #else
  146. /* Unfortunately, we can't get an unaligned access trap for the sub-word
  147.    load, so we have to do a general unaligned operation.  */
  148. #define __get_user_16(addr)
  149. {
  150. long __gu_tmp;
  151. __asm__("1: ldq_u %0,0(%3)n"
  152. "2: ldq_u %1,1(%3)n"
  153. " extwl %0,%3,%0n"
  154. " extwh %1,%3,%1n"
  155. " or %0,%1,%0n"
  156. "3:n"
  157. ".section __ex_table,"a"n"
  158. " .gprel32 1bn"
  159. " lda %0, 3b-1b(%2)n"
  160. " .gprel32 2bn"
  161. " lda %0, 2b-1b(%2)n"
  162. ".previous"
  163. : "=&r"(__gu_val), "=&r"(__gu_tmp), "=r"(__gu_err)
  164. : "r"(addr), "2"(__gu_err));
  165. }
  166. #define __get_user_8(addr)
  167. __asm__("1: ldq_u %0,0(%2)n"
  168. " extbl %0,%2,%0n"
  169. "2:n"
  170. ".section __ex_table,"a"n"
  171. " .gprel32 1bn"
  172. " lda %0, 2b-1b(%1)n"
  173. ".previous"
  174. : "=&r"(__gu_val), "=r"(__gu_err)
  175. : "r"(addr), "1"(__gu_err))
  176. #endif
  177. extern void __put_user_unknown(void);
  178. #define __put_user_nocheck(x,ptr,size)
  179. ({
  180. long __pu_err = 0;
  181. switch (size) {
  182.   case 1: __put_user_8(x,ptr); break;
  183.   case 2: __put_user_16(x,ptr); break;
  184.   case 4: __put_user_32(x,ptr); break;
  185.   case 8: __put_user_64(x,ptr); break;
  186.   default: __put_user_unknown(); break;
  187. }
  188. __pu_err;
  189. })
  190. #define __put_user_check(x,ptr,size,segment)
  191. ({
  192. long __pu_err = -EFAULT;
  193. __typeof__(*(ptr)) *__pu_addr = (ptr);
  194. if (__access_ok((long)__pu_addr,size,segment)) {
  195. __pu_err = 0;
  196. switch (size) {
  197.   case 1: __put_user_8(x,__pu_addr); break;
  198.   case 2: __put_user_16(x,__pu_addr); break;
  199.   case 4: __put_user_32(x,__pu_addr); break;
  200.   case 8: __put_user_64(x,__pu_addr); break;
  201.   default: __put_user_unknown(); break;
  202. }
  203. }
  204. __pu_err;
  205. })
  206. /*
  207.  * The "__put_user_xx()" macros tell gcc they read from memory
  208.  * instead of writing: this is because they do not write to
  209.  * any memory gcc knows about, so there are no aliasing issues
  210.  */
  211. #define __put_user_64(x,addr)
  212. __asm__ __volatile__("1: stq %r2,%1n"
  213. "2:n"
  214. ".section __ex_table,"a"n"
  215. " .gprel32 1bn"
  216. " lda $31,2b-1b(%0)n"
  217. ".previous"
  218. : "=r"(__pu_err)
  219. : "m" (__m(addr)), "rJ" (x), "0"(__pu_err))
  220. #define __put_user_32(x,addr)
  221. __asm__ __volatile__("1: stl %r2,%1n"
  222. "2:n"
  223. ".section __ex_table,"a"n"
  224. " .gprel32 1bn"
  225. " lda $31,2b-1b(%0)n"
  226. ".previous"
  227. : "=r"(__pu_err)
  228. : "m"(__m(addr)), "rJ"(x), "0"(__pu_err))
  229. #ifdef __alpha_bwx__
  230. /* Those lucky bastards with ev56 and later CPUs can do byte/word moves.  */
  231. #define __put_user_16(x,addr)
  232. __asm__ __volatile__("1: stw %r2,%1n"
  233. "2:n"
  234. ".section __ex_table,"a"n"
  235. " .gprel32 1bn"
  236. " lda $31,2b-1b(%0)n"
  237. ".previous"
  238. : "=r"(__pu_err)
  239. : "m"(__m(addr)), "rJ"(x), "0"(__pu_err))
  240. #define __put_user_8(x,addr)
  241. __asm__ __volatile__("1: stb %r2,%1n"
  242. "2:n"
  243. ".section __ex_table,"a"n"
  244. " .gprel32 1bn"
  245. " lda $31,2b-1b(%0)n"
  246. ".previous"
  247. : "=r"(__pu_err)
  248. : "m"(__m(addr)), "rJ"(x), "0"(__pu_err))
  249. #else
  250. /* Unfortunately, we can't get an unaligned access trap for the sub-word
  251.    write, so we have to do a general unaligned operation.  */
  252. #define __put_user_16(x,addr)
  253. {
  254. long __pu_tmp1, __pu_tmp2, __pu_tmp3, __pu_tmp4;
  255. __asm__ __volatile__(
  256. "1: ldq_u %2,1(%5)n"
  257. "2: ldq_u %1,0(%5)n"
  258. " inswh %6,%5,%4n"
  259. " inswl %6,%5,%3n"
  260. " mskwh %2,%5,%2n"
  261. " mskwl %1,%5,%1n"
  262. " or %2,%4,%2n"
  263. " or %1,%3,%1n"
  264. "3: stq_u %2,1(%5)n"
  265. "4: stq_u %1,0(%5)n"
  266. "5:n"
  267. ".section __ex_table,"a"n"
  268. " .gprel32 1bn"
  269. " lda $31, 5b-1b(%0)n"
  270. " .gprel32 2bn"
  271. " lda $31, 5b-2b(%0)n"
  272. " .gprel32 3bn"
  273. " lda $31, 5b-3b(%0)n"
  274. " .gprel32 4bn"
  275. " lda $31, 5b-4b(%0)n"
  276. ".previous"
  277. : "=r"(__pu_err), "=&r"(__pu_tmp1),
  278.   "=&r"(__pu_tmp2), "=&r"(__pu_tmp3),
  279.   "=&r"(__pu_tmp4)
  280. : "r"(addr), "r"((unsigned long)(x)), "0"(__pu_err)); 
  281. }
  282. #define __put_user_8(x,addr)
  283. {
  284. long __pu_tmp1, __pu_tmp2;
  285. __asm__ __volatile__(
  286. "1: ldq_u %1,0(%4)n"
  287. " insbl %3,%4,%2n"
  288. " mskbl %1,%4,%1n"
  289. " or %1,%2,%1n"
  290. "2: stq_u %1,0(%4)n"
  291. "3:n"
  292. ".section __ex_table,"a"n"
  293. " .gprel32 1bn"
  294. " lda $31, 3b-1b(%0)n"
  295. " .gprel32 2bn"
  296. " lda $31, 3b-2b(%0)n"
  297. ".previous"
  298. : "=r"(__pu_err),
  299.      "=&r"(__pu_tmp1), "=&r"(__pu_tmp2)
  300. : "r"((unsigned long)(x)), "r"(addr), "0"(__pu_err)); 
  301. }
  302. #endif
  303. /*
  304.  * Complex access routines
  305.  */
  306. extern void __copy_user(void);
  307. extern inline long
  308. __copy_tofrom_user_nocheck(void *to, const void *from, long len)
  309. {
  310. /* This little bit of silliness is to get the GP loaded for
  311.    a function that ordinarily wouldn't.  Otherwise we could
  312.    have it done by the macro directly, which can be optimized
  313.    the linker.  */
  314. register void * pv __asm__("$27") = __copy_user;
  315. register void * __cu_to __asm__("$6") = to;
  316. register const void * __cu_from __asm__("$7") = from;
  317. register long __cu_len __asm__("$0") = len;
  318. __asm__ __volatile__(
  319. "jsr $28,(%3),__copy_userntldgp $29,0($28)"
  320. : "=r" (__cu_len), "=r" (__cu_from), "=r" (__cu_to), "=r"(pv)
  321. : "0" (__cu_len), "1" (__cu_from), "2" (__cu_to), "3"(pv)
  322. : "$1","$2","$3","$4","$5","$28","memory");
  323. return __cu_len;
  324. }
  325. extern inline long
  326. __copy_tofrom_user(void *to, const void *from, long len, const void *validate)
  327. {
  328. if (__access_ok((long)validate, len, get_fs())) {
  329. register void * pv __asm__("$27") = __copy_user;
  330. register void * __cu_to __asm__("$6") = to;
  331. register const void * __cu_from __asm__("$7") = from;
  332. register long __cu_len __asm__("$0") = len;
  333. __asm__ __volatile__(
  334. "jsr $28,(%3),__copy_userntldgp $29,0($28)"
  335. : "=r"(__cu_len), "=r"(__cu_from), "=r"(__cu_to),
  336.   "=r" (pv)
  337. : "0" (__cu_len), "1" (__cu_from), "2" (__cu_to), 
  338.   "3" (pv)
  339. : "$1","$2","$3","$4","$5","$28","memory");
  340. len = __cu_len;
  341. }
  342. return len;
  343. }
  344. #define __copy_to_user(to,from,n)   __copy_tofrom_user_nocheck((to),(from),(n))
  345. #define __copy_from_user(to,from,n) __copy_tofrom_user_nocheck((to),(from),(n))
  346. extern inline long
  347. copy_to_user(void *to, const void *from, long n)
  348. {
  349. return __copy_tofrom_user(to, from, n, to);
  350. }
  351. extern inline long
  352. copy_from_user(void *to, const void *from, long n)
  353. {
  354. return __copy_tofrom_user(to, from, n, from);
  355. }
  356. extern void __do_clear_user(void);
  357. extern inline long
  358. __clear_user(void *to, long len)
  359. {
  360. /* This little bit of silliness is to get the GP loaded for
  361.    a function that ordinarily wouldn't.  Otherwise we could
  362.    have it done by the macro directly, which can be optimized
  363.    the linker.  */
  364. register void * pv __asm__("$27") = __do_clear_user;
  365. register void * __cl_to __asm__("$6") = to;
  366. register long __cl_len __asm__("$0") = len;
  367. __asm__ __volatile__(
  368. "jsr $28,(%2),__do_clear_userntldgp $29,0($28)"
  369. : "=r"(__cl_len), "=r"(__cl_to), "=r"(pv)
  370. : "0"(__cl_len), "1"(__cl_to), "2"(pv)
  371. : "$1","$2","$3","$4","$5","$28","memory");
  372. return __cl_len;
  373. }
  374. extern inline long
  375. clear_user(void *to, long len)
  376. {
  377. if (__access_ok((long)to, len, get_fs())) {
  378. register void * pv __asm__("$27") = __do_clear_user;
  379. register void * __cl_to __asm__("$6") = to;
  380. register long __cl_len __asm__("$0") = len;
  381. __asm__ __volatile__(
  382. "jsr $28,(%2),__do_clear_userntldgp $29,0($28)"
  383. : "=r"(__cl_len), "=r"(__cl_to), "=r"(pv)
  384. : "0"(__cl_len), "1"(__cl_to), "2"(pv)
  385. : "$1","$2","$3","$4","$5","$28","memory");
  386. len = __cl_len;
  387. }
  388. return len;
  389. }
  390. /* Returns: -EFAULT if exception before terminator, N if the entire
  391.    buffer filled, else strlen.  */
  392. extern long __strncpy_from_user(char *__to, const char *__from, long __to_len);
  393. extern inline long
  394. strncpy_from_user(char *to, const char *from, long n)
  395. {
  396. long ret = -EFAULT;
  397. if (__access_ok((long)from, 0, get_fs()))
  398. ret = __strncpy_from_user(to, from, n);
  399. return ret;
  400. }
  401. /* Returns: 0 if bad, string length+1 (memory size) of string if ok */
  402. extern long __strlen_user(const char *);
  403. extern inline long strlen_user(const char *str)
  404. {
  405. return access_ok(VERIFY_READ,str,0) ? __strlen_user(str) : 0;
  406. }
  407. /* Returns: 0 if exception before NUL or reaching the supplied limit (N),
  408.  * a value greater than N if the limit would be exceeded, else strlen.  */
  409. extern long __strnlen_user(const char *, long);
  410. extern inline long strnlen_user(const char *str, long n)
  411. {
  412. return access_ok(VERIFY_READ,str,0) ? __strnlen_user(str, n) : 0;
  413. }
  414. /*
  415.  * About the exception table:
  416.  *
  417.  * - insn is a 32-bit offset off of the kernel's or module's gp.
  418.  * - nextinsn is a 16-bit offset off of the faulting instruction
  419.  *   (not off of the *next* instruction as branches are).
  420.  * - errreg is the register in which to place -EFAULT.
  421.  * - valreg is the final target register for the load sequence
  422.  *   and will be zeroed.
  423.  *
  424.  * Either errreg or valreg may be $31, in which case nothing happens.
  425.  *
  426.  * The exception fixup information "just so happens" to be arranged
  427.  * as in a MEM format instruction.  This lets us emit our three
  428.  * values like so:
  429.  *
  430.  *      lda valreg, nextinsn(errreg)
  431.  *
  432.  */
  433. struct exception_table_entry
  434. {
  435. signed int insn;
  436. union exception_fixup {
  437. unsigned unit;
  438. struct {
  439. signed int nextinsn : 16;
  440. unsigned int errreg : 5;
  441. unsigned int valreg : 5;
  442. } bits;
  443. } fixup;
  444. };
  445. /* Returns 0 if exception not found and fixup.unit otherwise.  */
  446. extern unsigned search_exception_table(unsigned long, unsigned long);
  447. /* Returns the new pc */
  448. #define fixup_exception(map_reg, fixup_unit, pc)
  449. ({
  450. union exception_fixup __fie_fixup;
  451. __fie_fixup.unit = fixup_unit;
  452. if (__fie_fixup.bits.valreg != 31)
  453. map_reg(__fie_fixup.bits.valreg) = 0;
  454. if (__fie_fixup.bits.errreg != 31)
  455. map_reg(__fie_fixup.bits.errreg) = -EFAULT;
  456. (pc) + __fie_fixup.bits.nextinsn;
  457. })
  458. #endif /* __ALPHA_UACCESS_H */