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