clear_user.S 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
  4. */
  5. #include <linux/export.h>
  6. #include <asm/alternative-asm.h>
  7. #include <asm/asm.h>
  8. #include <asm/asmmacro.h>
  9. #include <asm/asm-extable.h>
  10. #include <asm/cpu.h>
  11. #include <asm/regdef.h>
  12. #include <asm/unwind_hints.h>
  13. SYM_FUNC_START(__clear_user)
  14. #ifdef CONFIG_32BIT
  15. b __clear_user_generic
  16. #else
  17. /*
  18. * Some CPUs support hardware unaligned access
  19. */
  20. ALTERNATIVE "b __clear_user_generic", \
  21. "b __clear_user_fast", CPU_FEATURE_UAL
  22. #endif
  23. SYM_FUNC_END(__clear_user)
  24. EXPORT_SYMBOL(__clear_user)
  25. /*
  26. * unsigned long __clear_user_generic(void *addr, size_t size)
  27. *
  28. * a0: addr
  29. * a1: size
  30. */
  31. SYM_FUNC_START(__clear_user_generic)
  32. beqz a1, 2f
  33. 1: st.b zero, a0, 0
  34. PTR_ADDI a0, a0, 1
  35. PTR_ADDI a1, a1, -1
  36. bgtz a1, 1b
  37. 2: move a0, a1
  38. jr ra
  39. _asm_extable 1b, 2b
  40. SYM_FUNC_END(__clear_user_generic)
  41. #ifdef CONFIG_64BIT
  42. /*
  43. * unsigned long __clear_user_fast(void *addr, unsigned long size)
  44. *
  45. * a0: addr
  46. * a1: size
  47. */
  48. SYM_FUNC_START(__clear_user_fast)
  49. sltui t0, a1, 9
  50. bnez t0, .Lsmall
  51. add.d a2, a0, a1
  52. 0: st.d zero, a0, 0
  53. /* align up address */
  54. addi.d a0, a0, 8
  55. bstrins.d a0, zero, 2, 0
  56. addi.d a3, a2, -64
  57. bgeu a0, a3, .Llt64
  58. /* set 64 bytes at a time */
  59. .Lloop64:
  60. 1: st.d zero, a0, 0
  61. 2: st.d zero, a0, 8
  62. 3: st.d zero, a0, 16
  63. 4: st.d zero, a0, 24
  64. 5: st.d zero, a0, 32
  65. 6: st.d zero, a0, 40
  66. 7: st.d zero, a0, 48
  67. 8: st.d zero, a0, 56
  68. addi.d a0, a0, 64
  69. bltu a0, a3, .Lloop64
  70. /* set the remaining bytes */
  71. .Llt64:
  72. addi.d a3, a2, -32
  73. bgeu a0, a3, .Llt32
  74. 9: st.d zero, a0, 0
  75. 10: st.d zero, a0, 8
  76. 11: st.d zero, a0, 16
  77. 12: st.d zero, a0, 24
  78. addi.d a0, a0, 32
  79. .Llt32:
  80. addi.d a3, a2, -16
  81. bgeu a0, a3, .Llt16
  82. 13: st.d zero, a0, 0
  83. 14: st.d zero, a0, 8
  84. addi.d a0, a0, 16
  85. .Llt16:
  86. addi.d a3, a2, -8
  87. bgeu a0, a3, .Llt8
  88. 15: st.d zero, a0, 0
  89. addi.d a0, a0, 8
  90. .Llt8:
  91. 16: st.d zero, a2, -8
  92. /* return */
  93. move a0, zero
  94. jr ra
  95. .align 4
  96. .Lsmall:
  97. pcaddi t0, 4
  98. slli.d a2, a1, 4
  99. add.d t0, t0, a2
  100. jr t0
  101. .align 4
  102. move a0, zero
  103. jr ra
  104. .align 4
  105. 17: st.b zero, a0, 0
  106. move a0, zero
  107. jr ra
  108. .align 4
  109. 18: st.h zero, a0, 0
  110. move a0, zero
  111. jr ra
  112. .align 4
  113. 19: st.h zero, a0, 0
  114. 20: st.b zero, a0, 2
  115. move a0, zero
  116. jr ra
  117. .align 4
  118. 21: st.w zero, a0, 0
  119. move a0, zero
  120. jr ra
  121. .align 4
  122. 22: st.w zero, a0, 0
  123. 23: st.b zero, a0, 4
  124. move a0, zero
  125. jr ra
  126. .align 4
  127. 24: st.w zero, a0, 0
  128. 25: st.h zero, a0, 4
  129. move a0, zero
  130. jr ra
  131. .align 4
  132. 26: st.w zero, a0, 0
  133. 27: st.w zero, a0, 3
  134. move a0, zero
  135. jr ra
  136. .align 4
  137. 28: st.d zero, a0, 0
  138. move a0, zero
  139. jr ra
  140. /* fixup and ex_table */
  141. .Llarge_fixup:
  142. sub.d a1, a2, a0
  143. .Lsmall_fixup:
  144. 29: st.b zero, a0, 0
  145. addi.d a0, a0, 1
  146. addi.d a1, a1, -1
  147. bgt a1, zero, 29b
  148. .Lexit:
  149. move a0, a1
  150. jr ra
  151. _asm_extable 0b, .Lsmall_fixup
  152. _asm_extable 1b, .Llarge_fixup
  153. _asm_extable 2b, .Llarge_fixup
  154. _asm_extable 3b, .Llarge_fixup
  155. _asm_extable 4b, .Llarge_fixup
  156. _asm_extable 5b, .Llarge_fixup
  157. _asm_extable 6b, .Llarge_fixup
  158. _asm_extable 7b, .Llarge_fixup
  159. _asm_extable 8b, .Llarge_fixup
  160. _asm_extable 9b, .Llarge_fixup
  161. _asm_extable 10b, .Llarge_fixup
  162. _asm_extable 11b, .Llarge_fixup
  163. _asm_extable 12b, .Llarge_fixup
  164. _asm_extable 13b, .Llarge_fixup
  165. _asm_extable 14b, .Llarge_fixup
  166. _asm_extable 15b, .Llarge_fixup
  167. _asm_extable 16b, .Llarge_fixup
  168. _asm_extable 17b, .Lexit
  169. _asm_extable 18b, .Lsmall_fixup
  170. _asm_extable 19b, .Lsmall_fixup
  171. _asm_extable 20b, .Lsmall_fixup
  172. _asm_extable 21b, .Lsmall_fixup
  173. _asm_extable 22b, .Lsmall_fixup
  174. _asm_extable 23b, .Lsmall_fixup
  175. _asm_extable 24b, .Lsmall_fixup
  176. _asm_extable 25b, .Lsmall_fixup
  177. _asm_extable 26b, .Lsmall_fixup
  178. _asm_extable 27b, .Lsmall_fixup
  179. _asm_extable 28b, .Lsmall_fixup
  180. _asm_extable 29b, .Lexit
  181. SYM_FUNC_END(__clear_user_fast)
  182. STACK_FRAME_NON_STANDARD __clear_user_fast
  183. #endif