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