]> git.karo-electronics.de Git - karo-tx-linux.git/blob - arch/arm64/lib/copy_in_user.S
1b94661e22b3f4dc3cf131f1afb6487333daee0b
[karo-tx-linux.git] / arch / arm64 / lib / copy_in_user.S
1 /*
2  * Copy from user space to user space
3  *
4  * Copyright (C) 2012 ARM Ltd.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include <linux/linkage.h>
20
21 #include <asm/alternative.h>
22 #include <asm/assembler.h>
23 #include <asm/cpufeature.h>
24 #include <asm/sysreg.h>
25
26 /*
27  * Copy from user space to user space (alignment handled by the hardware)
28  *
29  * Parameters:
30  *      x0 - to
31  *      x1 - from
32  *      x2 - n
33  * Returns:
34  *      x0 - bytes not copied
35  */
36 ENTRY(__copy_in_user)
37 ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_HAS_PAN, \
38             CONFIG_ARM64_PAN)
39         add     x5, x0, x2                      // upper user buffer boundary
40         subs    x2, x2, #16
41         b.mi    1f
42 0:
43 USER(9f, ldp    x3, x4, [x1], #16)
44         subs    x2, x2, #16
45 USER(9f, stp    x3, x4, [x0], #16)
46         b.pl    0b
47 1:      adds    x2, x2, #8
48         b.mi    2f
49 USER(9f, ldr    x3, [x1], #8    )
50         sub     x2, x2, #8
51 USER(9f, str    x3, [x0], #8    )
52 2:      adds    x2, x2, #4
53         b.mi    3f
54 USER(9f, ldr    w3, [x1], #4    )
55         sub     x2, x2, #4
56 USER(9f, str    w3, [x0], #4    )
57 3:      adds    x2, x2, #2
58         b.mi    4f
59 USER(9f, ldrh   w3, [x1], #2    )
60         sub     x2, x2, #2
61 USER(9f, strh   w3, [x0], #2    )
62 4:      adds    x2, x2, #1
63         b.mi    5f
64 USER(9f, ldrb   w3, [x1]        )
65 USER(9f, strb   w3, [x0]        )
66 5:      mov     x0, #0
67 ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_HAS_PAN, \
68             CONFIG_ARM64_PAN)
69         ret
70 ENDPROC(__copy_in_user)
71
72         .section .fixup,"ax"
73         .align  2
74 9:      sub     x0, x5, x0                      // bytes not copied
75         ret
76         .previous