copy_in_user.S 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /* copy_in_user.S: Copy from userspace to userspace.
  3. *
  4. * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com)
  5. */
  6. #include <linux/linkage.h>
  7. #include <asm/asi.h>
  8. #include <asm/export.h>
  9. #define XCC xcc
  10. #define EX(x,y,z) \
  11. 98: x,y; \
  12. .section __ex_table,"a";\
  13. .align 4; \
  14. .word 98b, z; \
  15. .text; \
  16. .align 4;
  17. #define EX_O4(x,y) EX(x,y,__retl_o4_plus_8)
  18. #define EX_O2_4(x,y) EX(x,y,__retl_o2_plus_4)
  19. #define EX_O2_1(x,y) EX(x,y,__retl_o2_plus_1)
  20. .register %g2,#scratch
  21. .register %g3,#scratch
  22. .text
  23. __retl_o4_plus_8:
  24. add %o4, %o2, %o4
  25. retl
  26. add %o4, 8, %o0
  27. __retl_o2_plus_4:
  28. retl
  29. add %o2, 4, %o0
  30. __retl_o2_plus_1:
  31. retl
  32. add %o2, 1, %o0
  33. .align 32
  34. /* Don't try to get too fancy here, just nice and
  35. * simple. This is predominantly used for well aligned
  36. * small copies in the compat layer. It is also used
  37. * to copy register windows around during thread cloning.
  38. */
  39. ENTRY(raw_copy_in_user) /* %o0=dst, %o1=src, %o2=len */
  40. cmp %o2, 0
  41. be,pn %XCC, 85f
  42. or %o0, %o1, %o3
  43. cmp %o2, 16
  44. bleu,a,pn %XCC, 80f
  45. or %o3, %o2, %o3
  46. /* 16 < len <= 64 */
  47. andcc %o3, 0x7, %g0
  48. bne,pn %XCC, 90f
  49. nop
  50. andn %o2, 0x7, %o4
  51. and %o2, 0x7, %o2
  52. 1: subcc %o4, 0x8, %o4
  53. EX_O4(ldxa [%o1] %asi, %o5)
  54. EX_O4(stxa %o5, [%o0] %asi)
  55. add %o1, 0x8, %o1
  56. bgu,pt %XCC, 1b
  57. add %o0, 0x8, %o0
  58. andcc %o2, 0x4, %g0
  59. be,pt %XCC, 1f
  60. nop
  61. sub %o2, 0x4, %o2
  62. EX_O2_4(lduwa [%o1] %asi, %o5)
  63. EX_O2_4(stwa %o5, [%o0] %asi)
  64. add %o1, 0x4, %o1
  65. add %o0, 0x4, %o0
  66. 1: cmp %o2, 0
  67. be,pt %XCC, 85f
  68. nop
  69. ba,pt %xcc, 90f
  70. nop
  71. 80: /* 0 < len <= 16 */
  72. andcc %o3, 0x3, %g0
  73. bne,pn %XCC, 90f
  74. nop
  75. 82:
  76. subcc %o2, 4, %o2
  77. EX_O2_4(lduwa [%o1] %asi, %g1)
  78. EX_O2_4(stwa %g1, [%o0] %asi)
  79. add %o1, 4, %o1
  80. bgu,pt %XCC, 82b
  81. add %o0, 4, %o0
  82. 85: retl
  83. clr %o0
  84. .align 32
  85. 90:
  86. subcc %o2, 1, %o2
  87. EX_O2_1(lduba [%o1] %asi, %g1)
  88. EX_O2_1(stba %g1, [%o0] %asi)
  89. add %o1, 1, %o1
  90. bgu,pt %XCC, 90b
  91. add %o0, 1, %o0
  92. retl
  93. clr %o0
  94. ENDPROC(raw_copy_in_user)
  95. EXPORT_SYMBOL(raw_copy_in_user)