Linux-libre 5.7.5-gnu
[librecmc/linux-libre.git] / arch / arm / lib / getuser.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  *  linux/arch/arm/lib/getuser.S
4  *
5  *  Copyright (C) 2001 Russell King
6  *
7  *  Idea from x86 version, (C) Copyright 1998 Linus Torvalds
8  *
9  * These functions have a non-standard call interface to make them more
10  * efficient, especially as they return an error value in addition to
11  * the "real" return value.
12  *
13  * __get_user_X
14  *
15  * Inputs:      r0 contains the address
16  *              r1 contains the address limit, which must be preserved
17  * Outputs:     r0 is the error code
18  *              r2, r3 contains the zero-extended value
19  *              lr corrupted
20  *
21  * No other registers must be altered.  (see <asm/uaccess.h>
22  * for specific ASM register usage).
23  *
24  * Note that ADDR_LIMIT is either 0 or 0xc0000000.
25  * Note also that it is intended that __get_user_bad is not global.
26  */
27 #include <linux/linkage.h>
28 #include <asm/assembler.h>
29 #include <asm/errno.h>
30 #include <asm/domain.h>
31
32 ENTRY(__get_user_1)
33         check_uaccess r0, 1, r1, r2, __get_user_bad
34 1: TUSER(ldrb)  r2, [r0]
35         mov     r0, #0
36         ret     lr
37 ENDPROC(__get_user_1)
38 _ASM_NOKPROBE(__get_user_1)
39
40 ENTRY(__get_user_2)
41         check_uaccess r0, 2, r1, r2, __get_user_bad
42 #if __LINUX_ARM_ARCH__ >= 6
43
44 2: TUSER(ldrh)  r2, [r0]
45
46 #else
47
48 #ifdef CONFIG_CPU_USE_DOMAINS
49 rb      .req    ip
50 2:      ldrbt   r2, [r0], #1
51 3:      ldrbt   rb, [r0], #0
52 #else
53 rb      .req    r0
54 2:      ldrb    r2, [r0]
55 3:      ldrb    rb, [r0, #1]
56 #endif
57 #ifndef __ARMEB__
58         orr     r2, r2, rb, lsl #8
59 #else
60         orr     r2, rb, r2, lsl #8
61 #endif
62
63 #endif /* __LINUX_ARM_ARCH__ >= 6 */
64
65         mov     r0, #0
66         ret     lr
67 ENDPROC(__get_user_2)
68 _ASM_NOKPROBE(__get_user_2)
69
70 ENTRY(__get_user_4)
71         check_uaccess r0, 4, r1, r2, __get_user_bad
72 4: TUSER(ldr)   r2, [r0]
73         mov     r0, #0
74         ret     lr
75 ENDPROC(__get_user_4)
76 _ASM_NOKPROBE(__get_user_4)
77
78 ENTRY(__get_user_8)
79         check_uaccess r0, 8, r1, r2, __get_user_bad8
80 #ifdef CONFIG_THUMB2_KERNEL
81 5: TUSER(ldr)   r2, [r0]
82 6: TUSER(ldr)   r3, [r0, #4]
83 #else
84 5: TUSER(ldr)   r2, [r0], #4
85 6: TUSER(ldr)   r3, [r0]
86 #endif
87         mov     r0, #0
88         ret     lr
89 ENDPROC(__get_user_8)
90 _ASM_NOKPROBE(__get_user_8)
91
92 #ifdef __ARMEB__
93 ENTRY(__get_user_32t_8)
94         check_uaccess r0, 8, r1, r2, __get_user_bad
95 #ifdef CONFIG_CPU_USE_DOMAINS
96         add     r0, r0, #4
97 7:      ldrt    r2, [r0]
98 #else
99 7:      ldr     r2, [r0, #4]
100 #endif
101         mov     r0, #0
102         ret     lr
103 ENDPROC(__get_user_32t_8)
104 _ASM_NOKPROBE(__get_user_32t_8)
105
106 ENTRY(__get_user_64t_1)
107         check_uaccess r0, 1, r1, r2, __get_user_bad8
108 8: TUSER(ldrb)  r3, [r0]
109         mov     r0, #0
110         ret     lr
111 ENDPROC(__get_user_64t_1)
112 _ASM_NOKPROBE(__get_user_64t_1)
113
114 ENTRY(__get_user_64t_2)
115         check_uaccess r0, 2, r1, r2, __get_user_bad8
116 #ifdef CONFIG_CPU_USE_DOMAINS
117 rb      .req    ip
118 9:      ldrbt   r3, [r0], #1
119 10:     ldrbt   rb, [r0], #0
120 #else
121 rb      .req    r0
122 9:      ldrb    r3, [r0]
123 10:     ldrb    rb, [r0, #1]
124 #endif
125         orr     r3, rb, r3, lsl #8
126         mov     r0, #0
127         ret     lr
128 ENDPROC(__get_user_64t_2)
129 _ASM_NOKPROBE(__get_user_64t_2)
130
131 ENTRY(__get_user_64t_4)
132         check_uaccess r0, 4, r1, r2, __get_user_bad8
133 11: TUSER(ldr)  r3, [r0]
134         mov     r0, #0
135         ret     lr
136 ENDPROC(__get_user_64t_4)
137 _ASM_NOKPROBE(__get_user_64t_4)
138 #endif
139
140 __get_user_bad8:
141         mov     r3, #0
142 __get_user_bad:
143         mov     r2, #0
144         mov     r0, #-EFAULT
145         ret     lr
146 ENDPROC(__get_user_bad)
147 ENDPROC(__get_user_bad8)
148 _ASM_NOKPROBE(__get_user_bad)
149 _ASM_NOKPROBE(__get_user_bad8)
150
151 .pushsection __ex_table, "a"
152         .long   1b, __get_user_bad
153         .long   2b, __get_user_bad
154 #if __LINUX_ARM_ARCH__ < 6
155         .long   3b, __get_user_bad
156 #endif
157         .long   4b, __get_user_bad
158         .long   5b, __get_user_bad8
159         .long   6b, __get_user_bad8
160 #ifdef __ARMEB__
161         .long   7b, __get_user_bad
162         .long   8b, __get_user_bad8
163         .long   9b, __get_user_bad8
164         .long   10b, __get_user_bad8
165         .long   11b, __get_user_bad8
166 #endif
167 .popsection