get rid of legacy 'get_ds()' function
[linux-2.6-block.git] / arch / s390 / include / asm / uaccess.h
CommitLineData
b2441318 1/* SPDX-License-Identifier: GPL-2.0 */
1da177e4 2/*
1da177e4 3 * S390 version
a53c8fab 4 * Copyright IBM Corp. 1999, 2000
1da177e4
LT
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 */
b5a882fc 16#include <asm/processor.h>
a0616cde 17#include <asm/ctl_reg.h>
e70f1d59 18#include <asm/extable.h>
0aaba41b 19#include <asm/facility.h>
1da177e4
LT
20
21/*
22 * The fs value determines whether argument validity checking should be
23 * performed or not. If get_fs() == USER_DS, checking is performed, with
24 * get_fs() == KERNEL_DS, checking is bypassed.
25 *
26 * For historical reasons, these macros are grossly misnamed.
27 */
28
0aaba41b
MS
29#define KERNEL_DS (0)
30#define KERNEL_DS_SACF (1)
31#define USER_DS (2)
32#define USER_DS_SACF (3)
1da177e4 33
1da177e4 34#define get_fs() (current->thread.mm_segment)
0aaba41b 35#define segment_eq(a,b) (((a) & 2) == ((b) & 2))
1da177e4 36
0aaba41b 37void set_fs(mm_segment_t fs);
b5a882fc 38
491af990
HC
39static inline int __range_ok(unsigned long addr, unsigned long size)
40{
41 return 1;
42}
43
44#define __access_ok(addr, size) \
45({ \
46 __chk_user_ptr(addr); \
47 __range_ok((unsigned long)(addr), (size)); \
7683f744 48})
1da177e4 49
96d4f267 50#define access_ok(addr, size) __access_ok(addr, size)
1da177e4 51
37096003
AV
52unsigned long __must_check
53raw_copy_from_user(void *to, const void __user *from, unsigned long n);
eb608fb3 54
37096003
AV
55unsigned long __must_check
56raw_copy_to_user(void __user *to, const void *from, unsigned long n);
d02765d1 57
37096003
AV
58#define INLINE_COPY_FROM_USER
59#define INLINE_COPY_TO_USER
6c1e3e79 60
c9ca7841
HC
61#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
62
63#define __put_get_user_asm(to, from, size, spec) \
64({ \
65 register unsigned long __reg0 asm("0") = spec; \
66 int __rc; \
67 \
68 asm volatile( \
69 "0: mvcos %1,%3,%2\n" \
70 "1: xr %0,%0\n" \
71 "2:\n" \
72 ".pushsection .fixup, \"ax\"\n" \
73 "3: lhi %0,%5\n" \
74 " jg 2b\n" \
75 ".popsection\n" \
76 EX_TABLE(0b,3b) EX_TABLE(1b,3b) \
d09c5373 77 : "=d" (__rc), "+Q" (*(to)) \
c9ca7841
HC
78 : "d" (size), "Q" (*(from)), \
79 "d" (__reg0), "K" (-EFAULT) \
80 : "cc"); \
81 __rc; \
82})
83
dc4aace1
HC
84static inline int __put_user_fn(void *x, void __user *ptr, unsigned long size)
85{
0aaba41b 86 unsigned long spec = 0x010000UL;
dc4aace1
HC
87 int rc;
88
89 switch (size) {
90 case 1:
91 rc = __put_get_user_asm((unsigned char __user *)ptr,
92 (unsigned char *)x,
93 size, spec);
94 break;
95 case 2:
96 rc = __put_get_user_asm((unsigned short __user *)ptr,
97 (unsigned short *)x,
98 size, spec);
99 break;
100 case 4:
101 rc = __put_get_user_asm((unsigned int __user *)ptr,
102 (unsigned int *)x,
103 size, spec);
104 break;
105 case 8:
106 rc = __put_get_user_asm((unsigned long __user *)ptr,
107 (unsigned long *)x,
108 size, spec);
109 break;
0b925159 110 }
dc4aace1
HC
111 return rc;
112}
113
114static inline int __get_user_fn(void *x, const void __user *ptr, unsigned long size)
115{
0aaba41b 116 unsigned long spec = 0x01UL;
dc4aace1
HC
117 int rc;
118
119 switch (size) {
120 case 1:
121 rc = __put_get_user_asm((unsigned char *)x,
122 (unsigned char __user *)ptr,
123 size, spec);
124 break;
125 case 2:
126 rc = __put_get_user_asm((unsigned short *)x,
127 (unsigned short __user *)ptr,
128 size, spec);
129 break;
130 case 4:
131 rc = __put_get_user_asm((unsigned int *)x,
132 (unsigned int __user *)ptr,
133 size, spec);
134 break;
135 case 8:
136 rc = __put_get_user_asm((unsigned long *)x,
137 (unsigned long __user *)ptr,
138 size, spec);
139 break;
0b925159 140 }
dc4aace1
HC
141 return rc;
142}
c9ca7841
HC
143
144#else /* CONFIG_HAVE_MARCH_Z10_FEATURES */
145
211deca6 146static inline int __put_user_fn(void *x, void __user *ptr, unsigned long size)
d02765d1 147{
37096003 148 size = raw_copy_to_user(ptr, x, size);
4f41c2b4 149 return size ? -EFAULT : 0;
d02765d1
GS
150}
151
211deca6 152static inline int __get_user_fn(void *x, const void __user *ptr, unsigned long size)
d02765d1 153{
37096003 154 size = raw_copy_from_user(x, ptr, size);
4f41c2b4 155 return size ? -EFAULT : 0;
d02765d1 156}
1da177e4 157
c9ca7841
HC
158#endif /* CONFIG_HAVE_MARCH_Z10_FEATURES */
159
1da177e4
LT
160/*
161 * These are the main single-value transfer routines. They automatically
162 * use the right size if we just have the right pointer type.
163 */
1da177e4
LT
164#define __put_user(x, ptr) \
165({ \
166 __typeof__(*(ptr)) __x = (x); \
d02765d1 167 int __pu_err = -EFAULT; \
17566c3c 168 __chk_user_ptr(ptr); \
1da177e4
LT
169 switch (sizeof (*(ptr))) { \
170 case 1: \
171 case 2: \
172 case 4: \
173 case 8: \
cfa785e6
HC
174 __pu_err = __put_user_fn(&__x, ptr, \
175 sizeof(*(ptr))); \
1da177e4
LT
176 break; \
177 default: \
178 __put_user_bad(); \
179 break; \
180 } \
ee64baf4 181 __builtin_expect(__pu_err, 0); \
1da177e4 182})
1da177e4
LT
183
184#define put_user(x, ptr) \
185({ \
dab4079d 186 might_fault(); \
1da177e4
LT
187 __put_user(x, ptr); \
188})
189
190
4f41c2b4 191int __put_user_bad(void) __attribute__((noreturn));
1da177e4 192
1da177e4
LT
193#define __get_user(x, ptr) \
194({ \
d02765d1
GS
195 int __gu_err = -EFAULT; \
196 __chk_user_ptr(ptr); \
1da177e4 197 switch (sizeof(*(ptr))) { \
1047aa77 198 case 1: { \
fd2d2b19 199 unsigned char __x = 0; \
cfa785e6
HC
200 __gu_err = __get_user_fn(&__x, ptr, \
201 sizeof(*(ptr))); \
97fa5a66 202 (x) = *(__force __typeof__(*(ptr)) *) &__x; \
1047aa77
MS
203 break; \
204 }; \
205 case 2: { \
fd2d2b19 206 unsigned short __x = 0; \
cfa785e6
HC
207 __gu_err = __get_user_fn(&__x, ptr, \
208 sizeof(*(ptr))); \
97fa5a66 209 (x) = *(__force __typeof__(*(ptr)) *) &__x; \
1047aa77
MS
210 break; \
211 }; \
212 case 4: { \
fd2d2b19 213 unsigned int __x = 0; \
cfa785e6
HC
214 __gu_err = __get_user_fn(&__x, ptr, \
215 sizeof(*(ptr))); \
97fa5a66 216 (x) = *(__force __typeof__(*(ptr)) *) &__x; \
1047aa77
MS
217 break; \
218 }; \
219 case 8: { \
fd2d2b19 220 unsigned long long __x = 0; \
cfa785e6
HC
221 __gu_err = __get_user_fn(&__x, ptr, \
222 sizeof(*(ptr))); \
97fa5a66 223 (x) = *(__force __typeof__(*(ptr)) *) &__x; \
1da177e4 224 break; \
1047aa77 225 }; \
1da177e4
LT
226 default: \
227 __get_user_bad(); \
228 break; \
229 } \
ee64baf4 230 __builtin_expect(__gu_err, 0); \
1da177e4 231})
1da177e4
LT
232
233#define get_user(x, ptr) \
234({ \
dab4079d 235 might_fault(); \
1da177e4
LT
236 __get_user(x, ptr); \
237})
238
4f41c2b4 239int __get_user_bad(void) __attribute__((noreturn));
1da177e4 240
4f41c2b4 241unsigned long __must_check
37096003 242raw_copy_in_user(void __user *to, const void __user *from, unsigned long n);
1da177e4
LT
243
244/*
245 * Copy a null terminated string from userspace.
246 */
4f41c2b4
HC
247
248long __strncpy_from_user(char *dst, const char __user *src, long count);
249
f7675ad7 250static inline long __must_check
1da177e4
LT
251strncpy_from_user(char *dst, const char __user *src, long count)
252{
dab4079d 253 might_fault();
4f41c2b4 254 return __strncpy_from_user(dst, src, count);
1da177e4
LT
255}
256
211deca6 257unsigned long __must_check __strnlen_user(const char __user *src, unsigned long count);
4f41c2b4 258
211deca6 259static inline unsigned long strnlen_user(const char __user *src, unsigned long n)
1da177e4 260{
dab4079d 261 might_fault();
4f41c2b4 262 return __strnlen_user(src, n);
1da177e4
LT
263}
264
1da177e4
LT
265/*
266 * Zero Userspace
267 */
211deca6 268unsigned long __must_check __clear_user(void __user *to, unsigned long size);
1da177e4 269
211deca6 270static inline unsigned long __must_check clear_user(void __user *to, unsigned long n)
1da177e4 271{
dab4079d 272 might_fault();
4f41c2b4 273 return __clear_user(to, n);
1da177e4
LT
274}
275
211deca6 276int copy_to_user_real(void __user *dest, void *src, unsigned long count);
8a5d8473 277void s390_kernel_write(void *dst, const void *src, size_t size);
a0616cde 278
1da177e4 279#endif /* __S390_UACCESS_H */