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