uaccess.S 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * arch/s390/lib/uaccess.S
  3. * __copy_{from|to}_user functions.
  4. *
  5. * s390
  6. * Copyright (C) 2000,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
  7. * Authors(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
  8. *
  9. * These functions have standard call interface
  10. */
  11. #include <linux/errno.h>
  12. #include <asm/lowcore.h>
  13. #include <asm/asm-offsets.h>
  14. .text
  15. .align 4
  16. .globl __copy_from_user_asm
  17. # %r2 = to, %r3 = n, %r4 = from
  18. __copy_from_user_asm:
  19. slr %r0,%r0
  20. 0: mvcp 0(%r3,%r2),0(%r4),%r0
  21. jnz 1f
  22. slr %r2,%r2
  23. br %r14
  24. 1: la %r2,256(%r2)
  25. la %r4,256(%r4)
  26. ahi %r3,-256
  27. 2: mvcp 0(%r3,%r2),0(%r4),%r0
  28. jnz 1b
  29. 3: slr %r2,%r2
  30. br %r14
  31. 4: lhi %r0,-4096
  32. lr %r5,%r4
  33. slr %r5,%r0
  34. nr %r5,%r0 # %r5 = (%r4 + 4096) & -4096
  35. slr %r5,%r4 # %r5 = #bytes to next user page boundary
  36. clr %r3,%r5 # copy crosses next page boundary ?
  37. jnh 6f # no, the current page faulted
  38. # move with the reduced length which is < 256
  39. 5: mvcp 0(%r5,%r2),0(%r4),%r0
  40. slr %r3,%r5
  41. 6: lr %r2,%r3
  42. br %r14
  43. .section __ex_table,"a"
  44. .long 0b,4b
  45. .long 2b,4b
  46. .long 5b,6b
  47. .previous
  48. .align 4
  49. .text
  50. .globl __copy_to_user_asm
  51. # %r2 = from, %r3 = n, %r4 = to
  52. __copy_to_user_asm:
  53. slr %r0,%r0
  54. 0: mvcs 0(%r3,%r4),0(%r2),%r0
  55. jnz 1f
  56. slr %r2,%r2
  57. br %r14
  58. 1: la %r2,256(%r2)
  59. la %r4,256(%r4)
  60. ahi %r3,-256
  61. 2: mvcs 0(%r3,%r4),0(%r2),%r0
  62. jnz 1b
  63. 3: slr %r2,%r2
  64. br %r14
  65. 4: lhi %r0,-4096
  66. lr %r5,%r4
  67. slr %r5,%r0
  68. nr %r5,%r0 # %r5 = (%r4 + 4096) & -4096
  69. slr %r5,%r4 # %r5 = #bytes to next user page boundary
  70. clr %r3,%r5 # copy crosses next page boundary ?
  71. jnh 6f # no, the current page faulted
  72. # move with the reduced length which is < 256
  73. 5: mvcs 0(%r5,%r4),0(%r2),%r0
  74. slr %r3,%r5
  75. 6: lr %r2,%r3
  76. br %r14
  77. .section __ex_table,"a"
  78. .long 0b,4b
  79. .long 2b,4b
  80. .long 5b,6b
  81. .previous
  82. .align 4
  83. .text
  84. .globl __copy_in_user_asm
  85. # %r2 = from, %r3 = n, %r4 = to
  86. __copy_in_user_asm:
  87. sacf 256
  88. bras 1,1f
  89. mvc 0(1,%r4),0(%r2)
  90. 0: mvc 0(256,%r4),0(%r2)
  91. la %r2,256(%r2)
  92. la %r4,256(%r4)
  93. 1: ahi %r3,-256
  94. jnm 0b
  95. 2: ex %r3,0(%r1)
  96. sacf 0
  97. slr %r2,%r2
  98. br 14
  99. 3: mvc 0(1,%r4),0(%r2)
  100. la %r2,1(%r2)
  101. la %r4,1(%r4)
  102. ahi %r3,-1
  103. jnm 3b
  104. 4: lr %r2,%r3
  105. sacf 0
  106. br %r14
  107. .section __ex_table,"a"
  108. .long 0b,3b
  109. .long 2b,3b
  110. .long 3b,4b
  111. .previous
  112. .align 4
  113. .text
  114. .globl __clear_user_asm
  115. # %r2 = to, %r3 = n
  116. __clear_user_asm:
  117. bras %r5,0f
  118. .long empty_zero_page
  119. 0: l %r5,0(%r5)
  120. slr %r0,%r0
  121. 1: mvcs 0(%r3,%r2),0(%r5),%r0
  122. jnz 2f
  123. slr %r2,%r2
  124. br %r14
  125. 2: la %r2,256(%r2)
  126. ahi %r3,-256
  127. 3: mvcs 0(%r3,%r2),0(%r5),%r0
  128. jnz 2b
  129. 4: slr %r2,%r2
  130. br %r14
  131. 5: lhi %r0,-4096
  132. lr %r4,%r2
  133. slr %r4,%r0
  134. nr %r4,%r0 # %r4 = (%r2 + 4096) & -4096
  135. slr %r4,%r2 # %r4 = #bytes to next user page boundary
  136. clr %r3,%r4 # clear crosses next page boundary ?
  137. jnh 7f # no, the current page faulted
  138. # clear with the reduced length which is < 256
  139. 6: mvcs 0(%r4,%r2),0(%r5),%r0
  140. slr %r3,%r4
  141. 7: lr %r2,%r3
  142. br %r14
  143. .section __ex_table,"a"
  144. .long 1b,5b
  145. .long 3b,5b
  146. .long 6b,7b
  147. .previous
  148. .align 4
  149. .text
  150. .globl __strncpy_from_user_asm
  151. # %r2 = count, %r3 = dst, %r4 = src
  152. __strncpy_from_user_asm:
  153. lhi %r0,0
  154. lr %r1,%r4
  155. la %r4,0(%r4) # clear high order bit from %r4
  156. la %r2,0(%r2,%r4) # %r2 points to first byte after string
  157. sacf 256
  158. 0: srst %r2,%r1
  159. jo 0b
  160. sacf 0
  161. lr %r1,%r2
  162. jh 1f # \0 found in string ?
  163. ahi %r1,1 # include \0 in copy
  164. 1: slr %r1,%r4 # %r1 = copy length (without \0)
  165. slr %r2,%r4 # %r2 = return length (including \0)
  166. 2: mvcp 0(%r1,%r3),0(%r4),%r0
  167. jnz 3f
  168. br %r14
  169. 3: la %r3,256(%r3)
  170. la %r4,256(%r4)
  171. ahi %r1,-256
  172. mvcp 0(%r1,%r3),0(%r4),%r0
  173. jnz 3b
  174. br %r14
  175. 4: sacf 0
  176. lhi %r2,-EFAULT
  177. br %r14
  178. .section __ex_table,"a"
  179. .long 0b,4b
  180. .previous
  181. .align 4
  182. .text
  183. .globl __strnlen_user_asm
  184. # %r2 = count, %r3 = src
  185. __strnlen_user_asm:
  186. lhi %r0,0
  187. lr %r1,%r3
  188. la %r3,0(%r3) # clear high order bit from %r4
  189. la %r2,0(%r2,%r3) # %r2 points to first byte after string
  190. sacf 256
  191. 0: srst %r2,%r1
  192. jo 0b
  193. sacf 0
  194. ahi %r2,1 # strnlen_user result includes the \0
  195. # or return count+1 if \0 not found
  196. slr %r2,%r3
  197. br %r14
  198. 2: sacf 0
  199. slr %r2,%r2 # return 0 on exception
  200. br %r14
  201. .section __ex_table,"a"
  202. .long 0b,2b
  203. .previous