s390/test_unwind: add kretprobe tests
[linux-2.6-microblaze.git] / arch / s390 / include / asm / uaccess.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  *  S390 version
4  *    Copyright IBM Corp. 1999, 2000
5  *    Author(s): Hartmut Penner (hp@de.ibm.com),
6  *               Martin Schwidefsky (schwidefsky@de.ibm.com)
7  *
8  *  Derived from "include/asm-i386/uaccess.h"
9  */
10 #ifndef __S390_UACCESS_H
11 #define __S390_UACCESS_H
12
13 /*
14  * User space memory access functions
15  */
16 #include <asm/asm-extable.h>
17 #include <asm/processor.h>
18 #include <asm/ctl_reg.h>
19 #include <asm/extable.h>
20 #include <asm/facility.h>
21
22 void debug_user_asce(int exit);
23
24 static inline int __range_ok(unsigned long addr, unsigned long size)
25 {
26         return 1;
27 }
28
29 #define __access_ok(addr, size)                         \
30 ({                                                      \
31         __chk_user_ptr(addr);                           \
32         __range_ok((unsigned long)(addr), (size));      \
33 })
34
35 #define access_ok(addr, size) __access_ok(addr, size)
36
37 unsigned long __must_check
38 raw_copy_from_user(void *to, const void __user *from, unsigned long n);
39
40 unsigned long __must_check
41 raw_copy_to_user(void __user *to, const void *from, unsigned long n);
42
43 #ifndef CONFIG_KASAN
44 #define INLINE_COPY_FROM_USER
45 #define INLINE_COPY_TO_USER
46 #endif
47
48 unsigned long __must_check
49 _copy_from_user_key(void *to, const void __user *from, unsigned long n, unsigned long key);
50
51 static __always_inline unsigned long __must_check
52 copy_from_user_key(void *to, const void __user *from, unsigned long n, unsigned long key)
53 {
54         if (likely(check_copy_size(to, n, false)))
55                 n = _copy_from_user_key(to, from, n, key);
56         return n;
57 }
58
59 unsigned long __must_check
60 _copy_to_user_key(void __user *to, const void *from, unsigned long n, unsigned long key);
61
62 static __always_inline unsigned long __must_check
63 copy_to_user_key(void __user *to, const void *from, unsigned long n, unsigned long key)
64 {
65         if (likely(check_copy_size(from, n, true)))
66                 n = _copy_to_user_key(to, from, n, key);
67         return n;
68 }
69
70 int __put_user_bad(void) __attribute__((noreturn));
71 int __get_user_bad(void) __attribute__((noreturn));
72
73 union oac {
74         unsigned int val;
75         struct {
76                 struct {
77                         unsigned short key : 4;
78                         unsigned short     : 4;
79                         unsigned short as  : 2;
80                         unsigned short     : 4;
81                         unsigned short k   : 1;
82                         unsigned short a   : 1;
83                 } oac1;
84                 struct {
85                         unsigned short key : 4;
86                         unsigned short     : 4;
87                         unsigned short as  : 2;
88                         unsigned short     : 4;
89                         unsigned short k   : 1;
90                         unsigned short a   : 1;
91                 } oac2;
92         };
93 };
94
95 #define __put_get_user_asm(to, from, size, oac_spec)                    \
96 ({                                                                      \
97         int __rc;                                                       \
98                                                                         \
99         asm volatile(                                                   \
100                 "       lr      0,%[spec]\n"                            \
101                 "0:     mvcos   %[_to],%[_from],%[_size]\n"             \
102                 "1:     xr      %[rc],%[rc]\n"                          \
103                 "2:\n"                                                  \
104                 EX_TABLE_UA(0b,2b,%[rc]) EX_TABLE_UA(1b,2b,%[rc])       \
105                 : [rc] "=&d" (__rc), [_to] "+Q" (*(to))                 \
106                 : [_size] "d" (size), [_from] "Q" (*(from)),            \
107                   [spec] "d" (oac_spec.val)                             \
108                 : "cc", "0");                                           \
109         __rc;                                                           \
110 })
111
112 #define __put_user_asm(to, from, size)                          \
113         __put_get_user_asm(to, from, size, ((union oac) {       \
114                 .oac1.as = PSW_BITS_AS_SECONDARY,               \
115                 .oac1.a = 1                                     \
116         }))
117
118 #define __get_user_asm(to, from, size)                          \
119         __put_get_user_asm(to, from, size, ((union oac) {       \
120                 .oac2.as = PSW_BITS_AS_SECONDARY,               \
121                 .oac2.a = 1                                     \
122         }))                                                     \
123
124 static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned long size)
125 {
126         int rc;
127
128         switch (size) {
129         case 1:
130                 rc = __put_user_asm((unsigned char __user *)ptr,
131                                     (unsigned char *)x,
132                                     size);
133                 break;
134         case 2:
135                 rc = __put_user_asm((unsigned short __user *)ptr,
136                                     (unsigned short *)x,
137                                     size);
138                 break;
139         case 4:
140                 rc = __put_user_asm((unsigned int __user *)ptr,
141                                     (unsigned int *)x,
142                                     size);
143                 break;
144         case 8:
145                 rc = __put_user_asm((unsigned long __user *)ptr,
146                                     (unsigned long *)x,
147                                     size);
148                 break;
149         default:
150                 __put_user_bad();
151                 break;
152         }
153         return rc;
154 }
155
156 static __always_inline int __get_user_fn(void *x, const void __user *ptr, unsigned long size)
157 {
158         int rc;
159
160         switch (size) {
161         case 1:
162                 rc = __get_user_asm((unsigned char *)x,
163                                     (unsigned char __user *)ptr,
164                                     size);
165                 break;
166         case 2:
167                 rc = __get_user_asm((unsigned short *)x,
168                                     (unsigned short __user *)ptr,
169                                     size);
170                 break;
171         case 4:
172                 rc = __get_user_asm((unsigned int *)x,
173                                     (unsigned int __user *)ptr,
174                                     size);
175                 break;
176         case 8:
177                 rc = __get_user_asm((unsigned long *)x,
178                                     (unsigned long __user *)ptr,
179                                     size);
180                 break;
181         default:
182                 __get_user_bad();
183                 break;
184         }
185         return rc;
186 }
187
188 /*
189  * These are the main single-value transfer routines.  They automatically
190  * use the right size if we just have the right pointer type.
191  */
192 #define __put_user(x, ptr) \
193 ({                                                              \
194         __typeof__(*(ptr)) __x = (x);                           \
195         int __pu_err = -EFAULT;                                 \
196         __chk_user_ptr(ptr);                                    \
197         switch (sizeof (*(ptr))) {                              \
198         case 1:                                                 \
199         case 2:                                                 \
200         case 4:                                                 \
201         case 8:                                                 \
202                 __pu_err = __put_user_fn(&__x, ptr,             \
203                                          sizeof(*(ptr)));       \
204                 break;                                          \
205         default:                                                \
206                 __put_user_bad();                               \
207                 break;                                          \
208         }                                                       \
209         __builtin_expect(__pu_err, 0);                          \
210 })
211
212 #define put_user(x, ptr)                                        \
213 ({                                                              \
214         might_fault();                                          \
215         __put_user(x, ptr);                                     \
216 })
217
218
219 #define __get_user(x, ptr)                                      \
220 ({                                                              \
221         int __gu_err = -EFAULT;                                 \
222         __chk_user_ptr(ptr);                                    \
223         switch (sizeof(*(ptr))) {                               \
224         case 1: {                                               \
225                 unsigned char __x = 0;                          \
226                 __gu_err = __get_user_fn(&__x, ptr,             \
227                                          sizeof(*(ptr)));       \
228                 (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
229                 break;                                          \
230         };                                                      \
231         case 2: {                                               \
232                 unsigned short __x = 0;                         \
233                 __gu_err = __get_user_fn(&__x, ptr,             \
234                                          sizeof(*(ptr)));       \
235                 (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
236                 break;                                          \
237         };                                                      \
238         case 4: {                                               \
239                 unsigned int __x = 0;                           \
240                 __gu_err = __get_user_fn(&__x, ptr,             \
241                                          sizeof(*(ptr)));       \
242                 (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
243                 break;                                          \
244         };                                                      \
245         case 8: {                                               \
246                 unsigned long long __x = 0;                     \
247                 __gu_err = __get_user_fn(&__x, ptr,             \
248                                          sizeof(*(ptr)));       \
249                 (x) = *(__force __typeof__(*(ptr)) *) &__x;     \
250                 break;                                          \
251         };                                                      \
252         default:                                                \
253                 __get_user_bad();                               \
254                 break;                                          \
255         }                                                       \
256         __builtin_expect(__gu_err, 0);                          \
257 })
258
259 #define get_user(x, ptr)                                        \
260 ({                                                              \
261         might_fault();                                          \
262         __get_user(x, ptr);                                     \
263 })
264
265 /*
266  * Copy a null terminated string from userspace.
267  */
268 long __must_check strncpy_from_user(char *dst, const char __user *src, long count);
269
270 long __must_check strnlen_user(const char __user *src, long count);
271
272 /*
273  * Zero Userspace
274  */
275 unsigned long __must_check __clear_user(void __user *to, unsigned long size);
276
277 static inline unsigned long __must_check clear_user(void __user *to, unsigned long n)
278 {
279         might_fault();
280         return __clear_user(to, n);
281 }
282
283 int copy_to_user_real(void __user *dest, unsigned long src, unsigned long count);
284 void *s390_kernel_write(void *dst, const void *src, size_t size);
285
286 #define HAVE_GET_KERNEL_NOFAULT
287
288 int __noreturn __put_kernel_bad(void);
289
290 #define __put_kernel_asm(val, to, insn)                                 \
291 ({                                                                      \
292         int __rc;                                                       \
293                                                                         \
294         asm volatile(                                                   \
295                 "0:   " insn "  %2,%1\n"                                \
296                 "1:     xr      %0,%0\n"                                \
297                 "2:\n"                                                  \
298                 EX_TABLE_UA(0b,2b,%0) EX_TABLE_UA(1b,2b,%0)             \
299                 : "=d" (__rc), "+Q" (*(to))                             \
300                 : "d" (val)                                             \
301                 : "cc");                                                \
302         __rc;                                                           \
303 })
304
305 #define __put_kernel_nofault(dst, src, type, err_label)                 \
306 do {                                                                    \
307         u64 __x = (u64)(*((type *)(src)));                              \
308         int __pk_err;                                                   \
309                                                                         \
310         switch (sizeof(type)) {                                         \
311         case 1:                                                         \
312                 __pk_err = __put_kernel_asm(__x, (type *)(dst), "stc"); \
313                 break;                                                  \
314         case 2:                                                         \
315                 __pk_err = __put_kernel_asm(__x, (type *)(dst), "sth"); \
316                 break;                                                  \
317         case 4:                                                         \
318                 __pk_err = __put_kernel_asm(__x, (type *)(dst), "st");  \
319                 break;                                                  \
320         case 8:                                                         \
321                 __pk_err = __put_kernel_asm(__x, (type *)(dst), "stg"); \
322                 break;                                                  \
323         default:                                                        \
324                 __pk_err = __put_kernel_bad();                          \
325                 break;                                                  \
326         }                                                               \
327         if (unlikely(__pk_err))                                         \
328                 goto err_label;                                         \
329 } while (0)
330
331 int __noreturn __get_kernel_bad(void);
332
333 #define __get_kernel_asm(val, from, insn)                               \
334 ({                                                                      \
335         int __rc;                                                       \
336                                                                         \
337         asm volatile(                                                   \
338                 "0:   " insn "  %1,%2\n"                                \
339                 "1:     xr      %0,%0\n"                                \
340                 "2:\n"                                                  \
341                 EX_TABLE_UA(0b,2b,%0) EX_TABLE_UA(1b,2b,%0)             \
342                 : "=d" (__rc), "+d" (val)                               \
343                 : "Q" (*(from))                                         \
344                 : "cc");                                                \
345         __rc;                                                           \
346 })
347
348 #define __get_kernel_nofault(dst, src, type, err_label)                 \
349 do {                                                                    \
350         int __gk_err;                                                   \
351                                                                         \
352         switch (sizeof(type)) {                                         \
353         case 1: {                                                       \
354                 u8 __x = 0;                                             \
355                                                                         \
356                 __gk_err = __get_kernel_asm(__x, (type *)(src), "ic");  \
357                 *((type *)(dst)) = (type)__x;                           \
358                 break;                                                  \
359         };                                                              \
360         case 2: {                                                       \
361                 u16 __x = 0;                                            \
362                                                                         \
363                 __gk_err = __get_kernel_asm(__x, (type *)(src), "lh");  \
364                 *((type *)(dst)) = (type)__x;                           \
365                 break;                                                  \
366         };                                                              \
367         case 4: {                                                       \
368                 u32 __x = 0;                                            \
369                                                                         \
370                 __gk_err = __get_kernel_asm(__x, (type *)(src), "l");   \
371                 *((type *)(dst)) = (type)__x;                           \
372                 break;                                                  \
373         };                                                              \
374         case 8: {                                                       \
375                 u64 __x = 0;                                            \
376                                                                         \
377                 __gk_err = __get_kernel_asm(__x, (type *)(src), "lg");  \
378                 *((type *)(dst)) = (type)__x;                           \
379                 break;                                                  \
380         };                                                              \
381         default:                                                        \
382                 __gk_err = __get_kernel_bad();                          \
383                 break;                                                  \
384         }                                                               \
385         if (unlikely(__gk_err))                                         \
386                 goto err_label;                                         \
387 } while (0)
388
389 #endif /* __S390_UACCESS_H */