Merge tag 'for-5.15/parisc' of git://git.kernel.org/pub/scm/linux/kernel/git/deller...
[linux-2.6-microblaze.git] / arch / csky / include / asm / uaccess.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2
3 #ifndef __ASM_CSKY_UACCESS_H
4 #define __ASM_CSKY_UACCESS_H
5
6 #define user_addr_max() \
7         (uaccess_kernel() ? KERNEL_DS.seg : get_fs().seg)
8
9 static inline int __access_ok(unsigned long addr, unsigned long size)
10 {
11         unsigned long limit = current_thread_info()->addr_limit.seg;
12
13         return ((addr < limit) && ((addr + size) < limit));
14 }
15 #define __access_ok __access_ok
16
17 /*
18  * __put_user_fn
19  */
20 extern int __put_user_bad(void);
21
22 #define __put_user_asm_b(x, ptr, err)                   \
23 do {                                                    \
24         int errcode;                                    \
25         __asm__ __volatile__(                           \
26         "1:     stb   %1, (%2,0)        \n"             \
27         "       br    3f                \n"             \
28         "2:     mov   %0, %3            \n"             \
29         "       br    3f                \n"             \
30         ".section __ex_table, \"a\"     \n"             \
31         ".align   2                     \n"             \
32         ".long    1b,2b                 \n"             \
33         ".previous                      \n"             \
34         "3:                             \n"             \
35         : "=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode)  \
36         : "0"(err), "1"(x), "2"(ptr), "3"(-EFAULT)      \
37         : "memory");                                    \
38 } while (0)
39
40 #define __put_user_asm_h(x, ptr, err)                   \
41 do {                                                    \
42         int errcode;                                    \
43         __asm__ __volatile__(                           \
44         "1:     sth   %1, (%2,0)        \n"             \
45         "       br    3f                \n"             \
46         "2:     mov   %0, %3            \n"             \
47         "       br    3f                \n"             \
48         ".section __ex_table, \"a\"     \n"             \
49         ".align   2                     \n"             \
50         ".long    1b,2b                 \n"             \
51         ".previous                      \n"             \
52         "3:                             \n"             \
53         : "=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode)  \
54         : "0"(err), "1"(x), "2"(ptr), "3"(-EFAULT)      \
55         : "memory");                                    \
56 } while (0)
57
58 #define __put_user_asm_w(x, ptr, err)                   \
59 do {                                                    \
60         int errcode;                                    \
61         __asm__ __volatile__(                           \
62         "1:     stw   %1, (%2,0)        \n"             \
63         "       br    3f                \n"             \
64         "2:     mov   %0, %3            \n"             \
65         "       br    3f                \n"             \
66         ".section __ex_table,\"a\"      \n"             \
67         ".align   2                     \n"             \
68         ".long    1b, 2b                \n"             \
69         ".previous                      \n"             \
70         "3:                             \n"             \
71         : "=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode)  \
72         : "0"(err), "1"(x), "2"(ptr), "3"(-EFAULT)      \
73         : "memory");                                    \
74 } while (0)
75
76 #define __put_user_asm_64(x, ptr, err)                  \
77 do {                                                    \
78         int tmp;                                        \
79         int errcode;                                    \
80                                                         \
81         __asm__ __volatile__(                           \
82         "     ldw     %3, (%1, 0)     \n"               \
83         "1:   stw     %3, (%2, 0)     \n"               \
84         "     ldw     %3, (%1, 4)     \n"               \
85         "2:   stw     %3, (%2, 4)     \n"               \
86         "     br      4f              \n"               \
87         "3:   mov     %0, %4          \n"               \
88         "     br      4f              \n"               \
89         ".section __ex_table, \"a\"   \n"               \
90         ".align   2                   \n"               \
91         ".long    1b, 3b              \n"               \
92         ".long    2b, 3b              \n"               \
93         ".previous                    \n"               \
94         "4:                           \n"               \
95         : "=r"(err), "=r"(x), "=r"(ptr),                \
96           "=r"(tmp), "=r"(errcode)                      \
97         : "0"(err), "1"(x), "2"(ptr), "3"(0),           \
98           "4"(-EFAULT)                                  \
99         : "memory");                                    \
100 } while (0)
101
102 static inline int __put_user_fn(size_t size, void __user *ptr, void *x)
103 {
104         int retval = 0;
105         u32 tmp;
106
107         switch (size) {
108         case 1:
109                 tmp = *(u8 *)x;
110                 __put_user_asm_b(tmp, ptr, retval);
111                 break;
112         case 2:
113                 tmp = *(u16 *)x;
114                 __put_user_asm_h(tmp, ptr, retval);
115                 break;
116         case 4:
117                 tmp = *(u32 *)x;
118                 __put_user_asm_w(tmp, ptr, retval);
119                 break;
120         case 8:
121                 __put_user_asm_64(x, (u64 *)ptr, retval);
122                 break;
123         }
124
125         return retval;
126 }
127 #define __put_user_fn __put_user_fn
128
129 /*
130  * __get_user_fn
131  */
132 extern int __get_user_bad(void);
133
134 #define __get_user_asm_common(x, ptr, ins, err)         \
135 do {                                                    \
136         int errcode;                                    \
137         __asm__ __volatile__(                           \
138         "1:   " ins " %1, (%4, 0)       \n"             \
139         "       br    3f                \n"             \
140         "2:     mov   %0, %2            \n"             \
141         "       movi  %1, 0             \n"             \
142         "       br    3f                \n"             \
143         ".section __ex_table,\"a\"      \n"             \
144         ".align   2                     \n"             \
145         ".long    1b, 2b                \n"             \
146         ".previous                      \n"             \
147         "3:                             \n"             \
148         : "=r"(err), "=r"(x), "=r"(errcode)             \
149         : "0"(0), "r"(ptr), "2"(-EFAULT)                \
150         : "memory");                                    \
151 } while (0)
152
153 #define __get_user_asm_64(x, ptr, err)                  \
154 do {                                                    \
155         int tmp;                                        \
156         int errcode;                                    \
157                                                         \
158         __asm__ __volatile__(                           \
159         "1:   ldw     %3, (%2, 0)     \n"               \
160         "     stw     %3, (%1, 0)     \n"               \
161         "2:   ldw     %3, (%2, 4)     \n"               \
162         "     stw     %3, (%1, 4)     \n"               \
163         "     br      4f              \n"               \
164         "3:   mov     %0, %4          \n"               \
165         "     br      4f              \n"               \
166         ".section __ex_table, \"a\"   \n"               \
167         ".align   2                   \n"               \
168         ".long    1b, 3b              \n"               \
169         ".long    2b, 3b              \n"               \
170         ".previous                    \n"               \
171         "4:                           \n"               \
172         : "=r"(err), "=r"(x), "=r"(ptr),                \
173           "=r"(tmp), "=r"(errcode)                      \
174         : "0"(err), "1"(x), "2"(ptr), "3"(0),           \
175           "4"(-EFAULT)                                  \
176         : "memory");                                    \
177 } while (0)
178
179 static inline int __get_user_fn(size_t size, const void __user *ptr, void *x)
180 {
181         int retval;
182         u32 tmp;
183
184         switch (size) {
185         case 1:
186                 __get_user_asm_common(tmp, ptr, "ldb", retval);
187                 *(u8 *)x = (u8)tmp;
188                 break;
189         case 2:
190                 __get_user_asm_common(tmp, ptr, "ldh", retval);
191                 *(u16 *)x = (u16)tmp;
192                 break;
193         case 4:
194                 __get_user_asm_common(tmp, ptr, "ldw", retval);
195                 *(u32 *)x = (u32)tmp;
196                 break;
197         case 8:
198                 __get_user_asm_64(x, ptr, retval);
199                 break;
200         }
201
202         return retval;
203 }
204 #define __get_user_fn __get_user_fn
205
206 unsigned long raw_copy_from_user(void *to, const void *from, unsigned long n);
207 unsigned long raw_copy_to_user(void *to, const void *from, unsigned long n);
208
209 unsigned long __clear_user(void __user *to, unsigned long n);
210 #define __clear_user __clear_user
211
212 #include <asm/segment.h>
213 #include <asm-generic/uaccess.h>
214
215 #endif /* __ASM_CSKY_UACCESS_H */