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