Merge tag 'sched-urgent-2020-12-27' of git://git.kernel.org/pub/scm/linux/kernel...
[linux/fpc-iii.git] / arch / riscv / lib / uaccess.S
blobfceaeb18cc6409c018510ba2eb5f6c4c657df50c
1 #include <linux/linkage.h>
2 #include <asm-generic/export.h>
3 #include <asm/asm.h>
4 #include <asm/csr.h>
6         .macro fixup op reg addr lbl
7 100:
8         \op \reg, \addr
9         .section __ex_table,"a"
10         .balign RISCV_SZPTR
11         RISCV_PTR 100b, \lbl
12         .previous
13         .endm
15 ENTRY(__asm_copy_to_user)
16 ENTRY(__asm_copy_from_user)
18         /* Enable access to user memory */
19         li t6, SR_SUM
20         csrs CSR_STATUS, t6
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
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
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
45         bltu a1, a3, 5f
48         /* Disable access to user memory */
49         csrc CSR_STATUS, t6
50         li a0, 0
51         ret
52 4: /* 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
59 5: /* 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
66 ENDPROC(__asm_copy_to_user)
67 ENDPROC(__asm_copy_from_user)
68 EXPORT_SYMBOL(__asm_copy_to_user)
69 EXPORT_SYMBOL(__asm_copy_from_user)
72 ENTRY(__clear_user)
74         /* Enable access to user memory */
75         li t6, SR_SUM
76         csrs CSR_STATUS, t6
78         add a3, a0, a1
79         addi t0, a0, SZREG-1
80         andi t1, a3, ~(SZREG-1)
81         andi t0, t0, ~(SZREG-1)
82         /*
83          * a3: terminal address of target region
84          * t0: lowest doubleword-aligned address in target region
85          * t1: highest doubleword-aligned address in target region
86          */
87         bgeu t0, t1, 2f
88         bltu a0, t0, 4f
90         fixup REG_S, zero, (a0), 11f
91         addi a0, a0, SZREG
92         bltu a0, t1, 1b
94         bltu a0, a3, 5f
97         /* Disable access to user memory */
98         csrc CSR_STATUS, t6
99         li a0, 0
100         ret
101 4: /* Edge case: unalignment */
102         fixup sb, zero, (a0), 11f
103         addi a0, a0, 1
104         bltu a0, t0, 4b
105         j 1b
106 5: /* Edge case: remainder */
107         fixup sb, zero, (a0), 11f
108         addi a0, a0, 1
109         bltu a0, a3, 5b
110         j 3b
111 ENDPROC(__clear_user)
112 EXPORT_SYMBOL(__clear_user)
114         .section .fixup,"ax"
115         .balign 4
116         /* Fixup code for __copy_user(10) and __clear_user(11) */
118         /* Disable access to user memory */
119         csrs CSR_STATUS, t6
120         mv a0, a2
121         ret
123         csrs CSR_STATUS, t6
124         mv a0, a1
125         ret
126         .previous