uaccess.S 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include <linux/linkage.h>
  2. #include <asm/asm.h>
  3. #include <asm/csr.h>
  4. .altmacro
  5. .macro fixup op reg addr lbl
  6. LOCAL _epc
  7. _epc:
  8. \op \reg, \addr
  9. .section __ex_table,"a"
  10. .balign RISCV_SZPTR
  11. RISCV_PTR _epc, \lbl
  12. .previous
  13. .endm
  14. ENTRY(__asm_copy_to_user)
  15. ENTRY(__asm_copy_from_user)
  16. /* Enable access to user memory */
  17. li t6, SR_SUM
  18. csrs sstatus, t6
  19. add a3, a1, a2
  20. /* Use word-oriented copy only if low-order bits match */
  21. andi t0, a0, SZREG-1
  22. andi t1, a1, SZREG-1
  23. bne t0, t1, 2f
  24. addi t0, a1, SZREG-1
  25. andi t1, a3, ~(SZREG-1)
  26. andi t0, t0, ~(SZREG-1)
  27. /*
  28. * a3: terminal address of source region
  29. * t0: lowest XLEN-aligned address in source
  30. * t1: highest XLEN-aligned address in source
  31. */
  32. bgeu t0, t1, 2f
  33. bltu a1, t0, 4f
  34. 1:
  35. fixup REG_L, t2, (a1), 10f
  36. fixup REG_S, t2, (a0), 10f
  37. addi a1, a1, SZREG
  38. addi a0, a0, SZREG
  39. bltu a1, t1, 1b
  40. 2:
  41. bltu a1, a3, 5f
  42. 3:
  43. /* Disable access to user memory */
  44. csrc sstatus, t6
  45. li a0, 0
  46. ret
  47. 4: /* Edge case: unalignment */
  48. fixup lbu, t2, (a1), 10f
  49. fixup sb, t2, (a0), 10f
  50. addi a1, a1, 1
  51. addi a0, a0, 1
  52. bltu a1, t0, 4b
  53. j 1b
  54. 5: /* Edge case: remainder */
  55. fixup lbu, t2, (a1), 10f
  56. fixup sb, t2, (a0), 10f
  57. addi a1, a1, 1
  58. addi a0, a0, 1
  59. bltu a1, a3, 5b
  60. j 3b
  61. ENDPROC(__asm_copy_to_user)
  62. ENDPROC(__asm_copy_from_user)
  63. ENTRY(__clear_user)
  64. /* Enable access to user memory */
  65. li t6, SR_SUM
  66. csrs sstatus, t6
  67. add a3, a0, a1
  68. addi t0, a0, SZREG-1
  69. andi t1, a3, ~(SZREG-1)
  70. andi t0, t0, ~(SZREG-1)
  71. /*
  72. * a3: terminal address of target region
  73. * t0: lowest doubleword-aligned address in target region
  74. * t1: highest doubleword-aligned address in target region
  75. */
  76. bgeu t0, t1, 2f
  77. bltu a0, t0, 4f
  78. 1:
  79. fixup REG_S, zero, (a0), 11f
  80. addi a0, a0, SZREG
  81. bltu a0, t1, 1b
  82. 2:
  83. bltu a0, a3, 5f
  84. 3:
  85. /* Disable access to user memory */
  86. csrc sstatus, t6
  87. li a0, 0
  88. ret
  89. 4: /* Edge case: unalignment */
  90. fixup sb, zero, (a0), 11f
  91. addi a0, a0, 1
  92. bltu a0, t0, 4b
  93. j 1b
  94. 5: /* Edge case: remainder */
  95. fixup sb, zero, (a0), 11f
  96. addi a0, a0, 1
  97. bltu a0, a3, 5b
  98. j 3b
  99. ENDPROC(__clear_user)
  100. .section .fixup,"ax"
  101. .balign 4
  102. /* Fixup code for __copy_user(10) and __clear_user(11) */
  103. 10:
  104. /* Disable access to user memory */
  105. csrs sstatus, t6
  106. mv a0, a2
  107. ret
  108. 11:
  109. csrs sstatus, t6
  110. mv a0, a1
  111. ret
  112. .previous