uaccess64.S 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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. 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: aghi %r3,-256
  94. jnm 0b
  95. 2: ex %r3,0(%r1)
  96. sacf 0
  97. slgr %r2,%r2
  98. br 14
  99. 3: mvc 0(1,%r4),0(%r2)
  100. la %r2,1(%r2)
  101. la %r4,1(%r4)
  102. aghi %r3,-1
  103. jnm 3b
  104. 4: lgr %r2,%r3
  105. sacf 0
  106. br %r14
  107. .section __ex_table,"a"
  108. .quad 0b,3b
  109. .quad 2b,3b
  110. .quad 3b,4b
  111. .previous
  112. .align 4
  113. .text
  114. .globl __clear_user_asm
  115. # %r2 = to, %r3 = n
  116. __clear_user_asm:
  117. slgr %r0,%r0
  118. larl %r5,empty_zero_page
  119. 1: mvcs 0(%r3,%r2),0(%r5),%r0
  120. jnz 2f
  121. slgr %r2,%r2
  122. br %r14
  123. 2: la %r2,256(%r2)
  124. aghi %r3,-256
  125. 3: mvcs 0(%r3,%r2),0(%r5),%r0
  126. jnz 2b
  127. 4: slgr %r2,%r2
  128. br %r14
  129. 5: lghi %r0,-4096
  130. lgr %r4,%r2
  131. slgr %r4,%r0
  132. ngr %r4,%r0 # %r4 = (%r2 + 4096) & -4096
  133. slgr %r4,%r2 # %r4 = #bytes to next user page boundary
  134. clgr %r3,%r4 # clear crosses next page boundary ?
  135. jnh 7f # no, the current page faulted
  136. # clear with the reduced length which is < 256
  137. 6: mvcs 0(%r4,%r2),0(%r5),%r0
  138. slgr %r3,%r4
  139. 7: lgr %r2,%r3
  140. br %r14
  141. .section __ex_table,"a"
  142. .quad 1b,5b
  143. .quad 3b,5b
  144. .quad 6b,7b
  145. .previous
  146. .align 4
  147. .text
  148. .globl __strncpy_from_user_asm
  149. # %r2 = count, %r3 = dst, %r4 = src
  150. __strncpy_from_user_asm:
  151. lghi %r0,0
  152. lgr %r1,%r4
  153. la %r2,0(%r2,%r4) # %r2 points to first byte after string
  154. sacf 256
  155. 0: srst %r2,%r1
  156. jo 0b
  157. sacf 0
  158. lgr %r1,%r2
  159. jh 1f # \0 found in string ?
  160. aghi %r1,1 # include \0 in copy
  161. 1: slgr %r1,%r4 # %r1 = copy length (without \0)
  162. slgr %r2,%r4 # %r2 = return length (including \0)
  163. 2: mvcp 0(%r1,%r3),0(%r4),%r0
  164. jnz 3f
  165. br %r14
  166. 3: la %r3,256(%r3)
  167. la %r4,256(%r4)
  168. aghi %r1,-256
  169. mvcp 0(%r1,%r3),0(%r4),%r0
  170. jnz 3b
  171. br %r14
  172. 4: sacf 0
  173. lghi %r2,-EFAULT
  174. br %r14
  175. .section __ex_table,"a"
  176. .quad 0b,4b
  177. .previous
  178. .align 4
  179. .text
  180. .globl __strnlen_user_asm
  181. # %r2 = count, %r3 = src
  182. __strnlen_user_asm:
  183. lghi %r0,0
  184. lgr %r1,%r3
  185. la %r2,0(%r2,%r3) # %r2 points to first byte after string
  186. sacf 256
  187. 0: srst %r2,%r1
  188. jo 0b
  189. sacf 0
  190. aghi %r2,1 # strnlen_user result includes the \0
  191. # or return count+1 if \0 not found
  192. slgr %r2,%r3
  193. br %r14
  194. 2: sacf 0
  195. slgr %r2,%r2 # return 0 on exception
  196. br %r14
  197. .section __ex_table,"a"
  198. .quad 0b,2b
  199. .previous