uaccess64.S 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. /*
  2. * arch/s390x/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. slgr %r0,%r0
  20. 0: mvcp 0(%r3,%r2),0(%r4),%r0
  21. jnz 1f
  22. slgr %r2,%r2
  23. br %r14
  24. 1: la %r2,256(%r2)
  25. la %r4,256(%r4)
  26. aghi %r3,-256
  27. 2: mvcp 0(%r3,%r2),0(%r4),%r0
  28. jnz 1b
  29. 3: slgr %r2,%r2
  30. br %r14
  31. 4: lghi %r0,-4096
  32. lgr %r5,%r4
  33. slgr %r5,%r0
  34. ngr %r5,%r0 # %r5 = (%r4 + 4096) & -4096
  35. slgr %r5,%r4 # %r5 = #bytes to next user page boundary
  36. clgr %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. slgr %r3,%r5
  41. 6: lgr %r2,%r3
  42. br %r14
  43. .section __ex_table,"a"
  44. .quad 0b,4b
  45. .quad 2b,4b
  46. .quad 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. slgr %r0,%r0
  54. 0: mvcs 0(%r3,%r4),0(%r2),%r0
  55. jnz 1f
  56. slgr %r2,%r2
  57. br %r14
  58. 1: la %r2,256(%r2)
  59. la %r4,256(%r4)
  60. aghi %r3,-256
  61. 2: mvcs 0(%r3,%r4),0(%r2),%r0
  62. jnz 1b
  63. 3: slgr %r2,%r2
  64. br %r14
  65. 4: lghi %r0,-4096
  66. lgr %r5,%r4
  67. slgr %r5,%r0
  68. ngr %r5,%r0 # %r5 = (%r4 + 4096) & -4096
  69. slgr %r5,%r4 # %r5 = #bytes to next user page boundary
  70. clgr %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. slgr %r3,%r5
  75. 6: lgr %r2,%r3
  76. br %r14
  77. .section __ex_table,"a"
  78. .quad 0b,4b
  79. .quad 2b,4b
  80. .quad 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. aghi %r3,-1
  88. jo 6f
  89. sacf 256
  90. bras %r1,4f
  91. 0: aghi %r3,257
  92. 1: mvc 0(1,%r4),0(%r2)
  93. la %r2,1(%r2)
  94. la %r4,1(%r4)
  95. aghi %r3,-1
  96. jnz 1b
  97. 2: lgr %r2,%r3
  98. br %r14
  99. 3: mvc 0(256,%r4),0(%r2)
  100. la %r2,256(%r2)
  101. la %r4,256(%r4)
  102. 4: aghi %r3,-256
  103. jnm 3b
  104. 5: ex %r3,4(%r1)
  105. sacf 0
  106. 6: slgr %r2,%r2
  107. br 14
  108. .section __ex_table,"a"
  109. .quad 1b,2b
  110. .quad 3b,0b
  111. .quad 5b,0b
  112. .previous
  113. .align 4
  114. .text
  115. .globl __clear_user_asm
  116. # %r2 = to, %r3 = n
  117. __clear_user_asm:
  118. slgr %r0,%r0
  119. larl %r5,empty_zero_page
  120. 1: mvcs 0(%r3,%r2),0(%r5),%r0
  121. jnz 2f
  122. slgr %r2,%r2
  123. br %r14
  124. 2: la %r2,256(%r2)
  125. aghi %r3,-256
  126. 3: mvcs 0(%r3,%r2),0(%r5),%r0
  127. jnz 2b
  128. 4: slgr %r2,%r2
  129. br %r14
  130. 5: lghi %r0,-4096
  131. lgr %r4,%r2
  132. slgr %r4,%r0
  133. ngr %r4,%r0 # %r4 = (%r2 + 4096) & -4096
  134. slgr %r4,%r2 # %r4 = #bytes to next user page boundary
  135. clgr %r3,%r4 # clear crosses next page boundary ?
  136. jnh 7f # no, the current page faulted
  137. # clear with the reduced length which is < 256
  138. 6: mvcs 0(%r4,%r2),0(%r5),%r0
  139. slgr %r3,%r4
  140. 7: lgr %r2,%r3
  141. br %r14
  142. .section __ex_table,"a"
  143. .quad 1b,5b
  144. .quad 3b,5b
  145. .quad 6b,7b
  146. .previous
  147. .align 4
  148. .text
  149. .globl __strncpy_from_user_asm
  150. # %r2 = count, %r3 = dst, %r4 = src
  151. __strncpy_from_user_asm:
  152. lghi %r0,0
  153. lgr %r1,%r4
  154. la %r2,0(%r2,%r4) # %r2 points to first byte after string
  155. sacf 256
  156. 0: srst %r2,%r1
  157. jo 0b
  158. sacf 0
  159. lgr %r1,%r2
  160. jh 1f # \0 found in string ?
  161. aghi %r1,1 # include \0 in copy
  162. 1: slgr %r1,%r4 # %r1 = copy length (without \0)
  163. slgr %r2,%r4 # %r2 = return length (including \0)
  164. 2: mvcp 0(%r1,%r3),0(%r4),%r0
  165. jnz 3f
  166. br %r14
  167. 3: la %r3,256(%r3)
  168. la %r4,256(%r4)
  169. aghi %r1,-256
  170. mvcp 0(%r1,%r3),0(%r4),%r0
  171. jnz 3b
  172. br %r14
  173. 4: sacf 0
  174. lghi %r2,-EFAULT
  175. br %r14
  176. .section __ex_table,"a"
  177. .quad 0b,4b
  178. .previous
  179. .align 4
  180. .text
  181. .globl __strnlen_user_asm
  182. # %r2 = count, %r3 = src
  183. __strnlen_user_asm:
  184. lghi %r0,0
  185. lgr %r1,%r3
  186. la %r2,0(%r2,%r3) # %r2 points to first byte after string
  187. sacf 256
  188. 0: srst %r2,%r1
  189. jo 0b
  190. sacf 0
  191. aghi %r2,1 # strnlen_user result includes the \0
  192. # or return count+1 if \0 not found
  193. slgr %r2,%r3
  194. br %r14
  195. 2: sacf 0
  196. slgr %r2,%r2 # return 0 on exception
  197. br %r14
  198. .section __ex_table,"a"
  199. .quad 0b,2b
  200. .previous