uaccess.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __ASM_CSKY_UACCESS_H
  3. #define __ASM_CSKY_UACCESS_H
  4. /*
  5. * __put_user_fn
  6. */
  7. extern int __put_user_bad(void);
  8. #define __put_user_asm_b(x, ptr, err) \
  9. do { \
  10. int errcode; \
  11. __asm__ __volatile__( \
  12. "1: stb %1, (%2,0) \n" \
  13. " br 3f \n" \
  14. "2: mov %0, %3 \n" \
  15. " br 3f \n" \
  16. ".section __ex_table, \"a\" \n" \
  17. ".align 2 \n" \
  18. ".long 1b,2b \n" \
  19. ".previous \n" \
  20. "3: \n" \
  21. : "=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode) \
  22. : "0"(err), "1"(x), "2"(ptr), "3"(-EFAULT) \
  23. : "memory"); \
  24. } while (0)
  25. #define __put_user_asm_h(x, ptr, err) \
  26. do { \
  27. int errcode; \
  28. __asm__ __volatile__( \
  29. "1: sth %1, (%2,0) \n" \
  30. " br 3f \n" \
  31. "2: mov %0, %3 \n" \
  32. " br 3f \n" \
  33. ".section __ex_table, \"a\" \n" \
  34. ".align 2 \n" \
  35. ".long 1b,2b \n" \
  36. ".previous \n" \
  37. "3: \n" \
  38. : "=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode) \
  39. : "0"(err), "1"(x), "2"(ptr), "3"(-EFAULT) \
  40. : "memory"); \
  41. } while (0)
  42. #define __put_user_asm_w(x, ptr, err) \
  43. do { \
  44. int errcode; \
  45. __asm__ __volatile__( \
  46. "1: stw %1, (%2,0) \n" \
  47. " br 3f \n" \
  48. "2: mov %0, %3 \n" \
  49. " br 3f \n" \
  50. ".section __ex_table,\"a\" \n" \
  51. ".align 2 \n" \
  52. ".long 1b, 2b \n" \
  53. ".previous \n" \
  54. "3: \n" \
  55. : "=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode) \
  56. : "0"(err), "1"(x), "2"(ptr), "3"(-EFAULT) \
  57. : "memory"); \
  58. } while (0)
  59. #define __put_user_asm_64(x, ptr, err) \
  60. do { \
  61. int tmp; \
  62. int errcode; \
  63. \
  64. __asm__ __volatile__( \
  65. " ldw %3, (%1, 0) \n" \
  66. "1: stw %3, (%2, 0) \n" \
  67. " ldw %3, (%1, 4) \n" \
  68. "2: stw %3, (%2, 4) \n" \
  69. " br 4f \n" \
  70. "3: mov %0, %4 \n" \
  71. " br 4f \n" \
  72. ".section __ex_table, \"a\" \n" \
  73. ".align 2 \n" \
  74. ".long 1b, 3b \n" \
  75. ".long 2b, 3b \n" \
  76. ".previous \n" \
  77. "4: \n" \
  78. : "=r"(err), "=r"(x), "=r"(ptr), \
  79. "=r"(tmp), "=r"(errcode) \
  80. : "0"(err), "1"(x), "2"(ptr), "3"(0), \
  81. "4"(-EFAULT) \
  82. : "memory"); \
  83. } while (0)
  84. static inline int __put_user_fn(size_t size, void __user *ptr, void *x)
  85. {
  86. int retval = 0;
  87. u32 tmp;
  88. switch (size) {
  89. case 1:
  90. tmp = *(u8 *)x;
  91. __put_user_asm_b(tmp, ptr, retval);
  92. break;
  93. case 2:
  94. tmp = *(u16 *)x;
  95. __put_user_asm_h(tmp, ptr, retval);
  96. break;
  97. case 4:
  98. tmp = *(u32 *)x;
  99. __put_user_asm_w(tmp, ptr, retval);
  100. break;
  101. case 8:
  102. __put_user_asm_64(x, (u64 *)ptr, retval);
  103. break;
  104. }
  105. return retval;
  106. }
  107. #define __put_user_fn __put_user_fn
  108. /*
  109. * __get_user_fn
  110. */
  111. extern int __get_user_bad(void);
  112. #define __get_user_asm_common(x, ptr, ins, err) \
  113. do { \
  114. int errcode; \
  115. __asm__ __volatile__( \
  116. "1: " ins " %1, (%4, 0) \n" \
  117. " br 3f \n" \
  118. "2: mov %0, %2 \n" \
  119. " movi %1, 0 \n" \
  120. " br 3f \n" \
  121. ".section __ex_table,\"a\" \n" \
  122. ".align 2 \n" \
  123. ".long 1b, 2b \n" \
  124. ".previous \n" \
  125. "3: \n" \
  126. : "=r"(err), "=r"(x), "=r"(errcode) \
  127. : "0"(0), "r"(ptr), "2"(-EFAULT) \
  128. : "memory"); \
  129. } while (0)
  130. #define __get_user_asm_64(x, ptr, err) \
  131. do { \
  132. int tmp; \
  133. int errcode; \
  134. \
  135. __asm__ __volatile__( \
  136. "1: ldw %3, (%2, 0) \n" \
  137. " stw %3, (%1, 0) \n" \
  138. "2: ldw %3, (%2, 4) \n" \
  139. " stw %3, (%1, 4) \n" \
  140. " br 4f \n" \
  141. "3: mov %0, %4 \n" \
  142. " br 4f \n" \
  143. ".section __ex_table, \"a\" \n" \
  144. ".align 2 \n" \
  145. ".long 1b, 3b \n" \
  146. ".long 2b, 3b \n" \
  147. ".previous \n" \
  148. "4: \n" \
  149. : "=r"(err), "=r"(x), "=r"(ptr), \
  150. "=r"(tmp), "=r"(errcode) \
  151. : "0"(err), "1"(x), "2"(ptr), "3"(0), \
  152. "4"(-EFAULT) \
  153. : "memory"); \
  154. } while (0)
  155. static inline int __get_user_fn(size_t size, const void __user *ptr, void *x)
  156. {
  157. int retval;
  158. u32 tmp;
  159. switch (size) {
  160. case 1:
  161. __get_user_asm_common(tmp, ptr, "ldb", retval);
  162. *(u8 *)x = (u8)tmp;
  163. break;
  164. case 2:
  165. __get_user_asm_common(tmp, ptr, "ldh", retval);
  166. *(u16 *)x = (u16)tmp;
  167. break;
  168. case 4:
  169. __get_user_asm_common(tmp, ptr, "ldw", retval);
  170. *(u32 *)x = (u32)tmp;
  171. break;
  172. case 8:
  173. __get_user_asm_64(x, ptr, retval);
  174. break;
  175. }
  176. return retval;
  177. }
  178. #define __get_user_fn __get_user_fn
  179. unsigned long raw_copy_from_user(void *to, const void *from, unsigned long n);
  180. unsigned long raw_copy_to_user(void *to, const void *from, unsigned long n);
  181. unsigned long __clear_user(void __user *to, unsigned long n);
  182. #define __clear_user __clear_user
  183. #include <asm-generic/uaccess.h>
  184. #endif /* __ASM_CSKY_UACCESS_H */