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