clear_user.S 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * This routine clears to zero a linear memory buffer in user space.
  4. *
  5. * Inputs:
  6. * in0: address of buffer
  7. * in1: length of buffer in bytes
  8. * Outputs:
  9. * r8: number of bytes that didn't get cleared due to a fault
  10. *
  11. * Copyright (C) 1998, 1999, 2001 Hewlett-Packard Co
  12. * Stephane Eranian <eranian@hpl.hp.com>
  13. */
  14. #include <asm/asmmacro.h>
  15. #include <asm/export.h>
  16. //
  17. // arguments
  18. //
  19. #define buf r32
  20. #define len r33
  21. //
  22. // local registers
  23. //
  24. #define cnt r16
  25. #define buf2 r17
  26. #define saved_lc r18
  27. #define saved_pfs r19
  28. #define tmp r20
  29. #define len2 r21
  30. #define len3 r22
  31. //
  32. // Theory of operations:
  33. // - we check whether or not the buffer is small, i.e., less than 17
  34. // in which case we do the byte by byte loop.
  35. //
  36. // - Otherwise we go progressively from 1 byte store to 8byte store in
  37. // the head part, the body is a 16byte store loop and we finish we the
  38. // tail for the last 15 bytes.
  39. // The good point about this breakdown is that the long buffer handling
  40. // contains only 2 branches.
  41. //
  42. // The reason for not using shifting & masking for both the head and the
  43. // tail is to stay semantically correct. This routine is not supposed
  44. // to write bytes outside of the buffer. While most of the time this would
  45. // be ok, we can't tolerate a mistake. A classical example is the case
  46. // of multithreaded code were to the extra bytes touched is actually owned
  47. // by another thread which runs concurrently to ours. Another, less likely,
  48. // example is with device drivers where reading an I/O mapped location may
  49. // have side effects (same thing for writing).
  50. //
  51. GLOBAL_ENTRY(__do_clear_user)
  52. .prologue
  53. .save ar.pfs, saved_pfs
  54. alloc saved_pfs=ar.pfs,2,0,0,0
  55. cmp.eq p6,p0=r0,len // check for zero length
  56. .save ar.lc, saved_lc
  57. mov saved_lc=ar.lc // preserve ar.lc (slow)
  58. .body
  59. ;; // avoid WAW on CFM
  60. adds tmp=-1,len // br.ctop is repeat/until
  61. mov ret0=len // return value is length at this point
  62. (p6) br.ret.spnt.many rp
  63. ;;
  64. cmp.lt p6,p0=16,len // if len > 16 then long memset
  65. mov ar.lc=tmp // initialize lc for small count
  66. (p6) br.cond.dptk .long_do_clear
  67. ;; // WAR on ar.lc
  68. //
  69. // worst case 16 iterations, avg 8 iterations
  70. //
  71. // We could have played with the predicates to use the extra
  72. // M slot for 2 stores/iteration but the cost the initialization
  73. // the various counters compared to how long the loop is supposed
  74. // to last on average does not make this solution viable.
  75. //
  76. 1:
  77. EX( .Lexit1, st1 [buf]=r0,1 )
  78. adds len=-1,len // countdown length using len
  79. br.cloop.dptk 1b
  80. ;; // avoid RAW on ar.lc
  81. //
  82. // .Lexit4: comes from byte by byte loop
  83. // len contains bytes left
  84. .Lexit1:
  85. mov ret0=len // faster than using ar.lc
  86. mov ar.lc=saved_lc
  87. br.ret.sptk.many rp // end of short clear_user
  88. //
  89. // At this point we know we have more than 16 bytes to copy
  90. // so we focus on alignment (no branches required)
  91. //
  92. // The use of len/len2 for countdown of the number of bytes left
  93. // instead of ret0 is due to the fact that the exception code
  94. // changes the values of r8.
  95. //
  96. .long_do_clear:
  97. tbit.nz p6,p0=buf,0 // odd alignment (for long_do_clear)
  98. ;;
  99. EX( .Lexit3, (p6) st1 [buf]=r0,1 ) // 1-byte aligned
  100. (p6) adds len=-1,len;; // sync because buf is modified
  101. tbit.nz p6,p0=buf,1
  102. ;;
  103. EX( .Lexit3, (p6) st2 [buf]=r0,2 ) // 2-byte aligned
  104. (p6) adds len=-2,len;;
  105. tbit.nz p6,p0=buf,2
  106. ;;
  107. EX( .Lexit3, (p6) st4 [buf]=r0,4 ) // 4-byte aligned
  108. (p6) adds len=-4,len;;
  109. tbit.nz p6,p0=buf,3
  110. ;;
  111. EX( .Lexit3, (p6) st8 [buf]=r0,8 ) // 8-byte aligned
  112. (p6) adds len=-8,len;;
  113. shr.u cnt=len,4 // number of 128-bit (2x64bit) words
  114. ;;
  115. cmp.eq p6,p0=r0,cnt
  116. adds tmp=-1,cnt
  117. (p6) br.cond.dpnt .dotail // we have less than 16 bytes left
  118. ;;
  119. adds buf2=8,buf // setup second base pointer
  120. mov ar.lc=tmp
  121. ;;
  122. //
  123. // 16bytes/iteration core loop
  124. //
  125. // The second store can never generate a fault because
  126. // we come into the loop only when we are 16-byte aligned.
  127. // This means that if we cross a page then it will always be
  128. // in the first store and never in the second.
  129. //
  130. //
  131. // We need to keep track of the remaining length. A possible (optimistic)
  132. // way would be to use ar.lc and derive how many byte were left by
  133. // doing : left= 16*ar.lc + 16. this would avoid the addition at
  134. // every iteration.
  135. // However we need to keep the synchronization point. A template
  136. // M;;MB does not exist and thus we can keep the addition at no
  137. // extra cycle cost (use a nop slot anyway). It also simplifies the
  138. // (unlikely) error recovery code
  139. //
  140. 2: EX(.Lexit3, st8 [buf]=r0,16 )
  141. ;; // needed to get len correct when error
  142. st8 [buf2]=r0,16
  143. adds len=-16,len
  144. br.cloop.dptk 2b
  145. ;;
  146. mov ar.lc=saved_lc
  147. //
  148. // tail correction based on len only
  149. //
  150. // We alternate the use of len3,len2 to allow parallelism and correct
  151. // error handling. We also reuse p6/p7 to return correct value.
  152. // The addition of len2/len3 does not cost anything more compared to
  153. // the regular memset as we had empty slots.
  154. //
  155. .dotail:
  156. mov len2=len // for parallelization of error handling
  157. mov len3=len
  158. tbit.nz p6,p0=len,3
  159. ;;
  160. EX( .Lexit2, (p6) st8 [buf]=r0,8 ) // at least 8 bytes
  161. (p6) adds len3=-8,len2
  162. tbit.nz p7,p6=len,2
  163. ;;
  164. EX( .Lexit2, (p7) st4 [buf]=r0,4 ) // at least 4 bytes
  165. (p7) adds len2=-4,len3
  166. tbit.nz p6,p7=len,1
  167. ;;
  168. EX( .Lexit2, (p6) st2 [buf]=r0,2 ) // at least 2 bytes
  169. (p6) adds len3=-2,len2
  170. tbit.nz p7,p6=len,0
  171. ;;
  172. EX( .Lexit2, (p7) st1 [buf]=r0 ) // only 1 byte left
  173. mov ret0=r0 // success
  174. br.ret.sptk.many rp // end of most likely path
  175. //
  176. // Outlined error handling code
  177. //
  178. //
  179. // .Lexit3: comes from core loop, need restore pr/lc
  180. // len contains bytes left
  181. //
  182. //
  183. // .Lexit2:
  184. // if p6 -> coming from st8 or st2 : len2 contains what's left
  185. // if p7 -> coming from st4 or st1 : len3 contains what's left
  186. // We must restore lc/pr even though might not have been used.
  187. .Lexit2:
  188. .pred.rel "mutex", p6, p7
  189. (p6) mov len=len2
  190. (p7) mov len=len3
  191. ;;
  192. //
  193. // .Lexit4: comes from head, need not restore pr/lc
  194. // len contains bytes left
  195. //
  196. .Lexit3:
  197. mov ret0=len
  198. mov ar.lc=saved_lc
  199. br.ret.sptk.many rp
  200. END(__do_clear_user)
  201. EXPORT_SYMBOL(__do_clear_user)