13
13
/*
14
14
* User space memory access functions
15
15
*/
16
-
17
- extern unsigned long __must_check __asm_copy_to_user (void __user * to ,
18
- const void * from , unsigned long n );
19
- extern unsigned long __must_check __asm_copy_from_user (void * to ,
20
- const void __user * from , unsigned long n );
21
-
22
- static inline unsigned long
23
- raw_copy_from_user (void * to , const void __user * from , unsigned long n )
24
- {
25
- return __asm_copy_from_user (to , from , n );
26
- }
27
-
28
- static inline unsigned long
29
- raw_copy_to_user (void __user * to , const void * from , unsigned long n )
30
- {
31
- return __asm_copy_to_user (to , from , n );
32
- }
33
-
34
16
#ifdef CONFIG_MMU
35
17
#include <linux/errno.h>
36
18
#include <linux/compiler.h>
@@ -44,29 +26,6 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n)
44
26
#define __disable_user_access () \
45
27
__asm__ __volatile__ ("csrc sstatus, %0" : : "r" (SR_SUM) : "memory")
46
28
47
- /*
48
- * The fs value determines whether argument validity checking should be
49
- * performed or not. If get_fs() == USER_DS, checking is performed, with
50
- * get_fs() == KERNEL_DS, checking is bypassed.
51
- *
52
- * For historical reasons, these macros are grossly misnamed.
53
- */
54
-
55
- #define MAKE_MM_SEG (s ) ((mm_segment_t) { (s) })
56
-
57
- #define KERNEL_DS MAKE_MM_SEG(~0UL)
58
- #define USER_DS MAKE_MM_SEG(TASK_SIZE)
59
-
60
- #define get_fs () (current_thread_info()->addr_limit)
61
-
62
- static inline void set_fs (mm_segment_t fs )
63
- {
64
- current_thread_info ()-> addr_limit = fs ;
65
- }
66
-
67
- #define uaccess_kernel () (get_fs().seg == KERNEL_DS.seg)
68
- #define user_addr_max () (get_fs().seg)
69
-
70
29
/**
71
30
* access_ok: - Checks if a user space pointer is valid
72
31
* @addr: User space pointer to start of block to check
@@ -94,9 +53,7 @@ static inline void set_fs(mm_segment_t fs)
94
53
*/
95
54
static inline int __access_ok (unsigned long addr , unsigned long size )
96
55
{
97
- const mm_segment_t fs = get_fs ();
98
-
99
- return size <= fs .seg && addr <= fs .seg - size ;
56
+ return size <= TASK_SIZE && addr <= TASK_SIZE - size ;
100
57
}
101
58
102
59
/*
@@ -125,7 +82,6 @@ static inline int __access_ok(unsigned long addr, unsigned long size)
125
82
do { \
126
83
uintptr_t __tmp; \
127
84
__typeof__(x) __x; \
128
- __enable_user_access(); \
129
85
__asm__ __volatile__ ( \
130
86
"1:\n" \
131
87
" " insn " %1, %3\n" \
@@ -143,7 +99,6 @@ do { \
143
99
" .previous" \
144
100
: "+r" (err), "=&r" (__x), "=r" (__tmp) \
145
101
: "m" (*(ptr)), "i" (-EFAULT)); \
146
- __disable_user_access(); \
147
102
(x) = __x; \
148
103
} while (0)
149
104
@@ -156,7 +111,6 @@ do { \
156
111
u32 __user *__ptr = (u32 __user *)(ptr); \
157
112
u32 __lo, __hi; \
158
113
uintptr_t __tmp; \
159
- __enable_user_access(); \
160
114
__asm__ __volatile__ ( \
161
115
"1:\n" \
162
116
" lw %1, %4\n" \
@@ -180,12 +134,30 @@ do { \
180
134
"=r" (__tmp) \
181
135
: "m" (__ptr[__LSW]), "m" (__ptr[__MSW]), \
182
136
"i" (-EFAULT)); \
183
- __disable_user_access(); \
184
137
(x) = (__typeof__(x))((__typeof__((x)-(x)))( \
185
138
(((u64)__hi << 32) | __lo))); \
186
139
} while (0)
187
140
#endif /* CONFIG_64BIT */
188
141
142
+ #define __get_user_nocheck (x , __gu_ptr , __gu_err ) \
143
+ do { \
144
+ switch (sizeof(*__gu_ptr)) { \
145
+ case 1: \
146
+ __get_user_asm("lb", (x), __gu_ptr, __gu_err); \
147
+ break; \
148
+ case 2: \
149
+ __get_user_asm("lh", (x), __gu_ptr, __gu_err); \
150
+ break; \
151
+ case 4: \
152
+ __get_user_asm("lw", (x), __gu_ptr, __gu_err); \
153
+ break; \
154
+ case 8: \
155
+ __get_user_8((x), __gu_ptr, __gu_err); \
156
+ break; \
157
+ default: \
158
+ BUILD_BUG(); \
159
+ } \
160
+ } while (0)
189
161
190
162
/**
191
163
* __get_user: - Get a simple variable from user space, with less checking.
@@ -209,25 +181,15 @@ do { \
209
181
*/
210
182
#define __get_user (x , ptr ) \
211
183
({ \
212
- register long __gu_err = 0; \
213
184
const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \
185
+ long __gu_err = 0; \
186
+ \
214
187
__chk_user_ptr(__gu_ptr); \
215
- switch (sizeof(*__gu_ptr)) { \
216
- case 1: \
217
- __get_user_asm("lb", (x), __gu_ptr, __gu_err); \
218
- break; \
219
- case 2: \
220
- __get_user_asm("lh", (x), __gu_ptr, __gu_err); \
221
- break; \
222
- case 4: \
223
- __get_user_asm("lw", (x), __gu_ptr, __gu_err); \
224
- break; \
225
- case 8: \
226
- __get_user_8((x), __gu_ptr, __gu_err); \
227
- break; \
228
- default: \
229
- BUILD_BUG(); \
230
- } \
188
+ \
189
+ __enable_user_access(); \
190
+ __get_user_nocheck(x, __gu_ptr, __gu_err); \
191
+ __disable_user_access(); \
192
+ \
231
193
__gu_err; \
232
194
})
233
195
@@ -261,7 +223,6 @@ do { \
261
223
do { \
262
224
uintptr_t __tmp; \
263
225
__typeof__(*(ptr)) __x = x; \
264
- __enable_user_access(); \
265
226
__asm__ __volatile__ ( \
266
227
"1:\n" \
267
228
" " insn " %z3, %2\n" \
@@ -278,7 +239,6 @@ do { \
278
239
" .previous" \
279
240
: "+r" (err), "=r" (__tmp), "=m" (*(ptr)) \
280
241
: "rJ" (__x), "i" (-EFAULT)); \
281
- __disable_user_access(); \
282
242
} while (0)
283
243
284
244
#ifdef CONFIG_64BIT
@@ -290,7 +250,6 @@ do { \
290
250
u32 __user *__ptr = (u32 __user *)(ptr); \
291
251
u64 __x = (__typeof__((x)-(x)))(x); \
292
252
uintptr_t __tmp; \
293
- __enable_user_access(); \
294
253
__asm__ __volatile__ ( \
295
254
"1:\n" \
296
255
" sw %z4, %2\n" \
@@ -312,10 +271,28 @@ do { \
312
271
"=m" (__ptr[__LSW]), \
313
272
"=m" (__ptr[__MSW]) \
314
273
: "rJ" (__x), "rJ" (__x >> 32), "i" (-EFAULT)); \
315
- __disable_user_access(); \
316
274
} while (0)
317
275
#endif /* CONFIG_64BIT */
318
276
277
+ #define __put_user_nocheck (x , __gu_ptr , __pu_err ) \
278
+ do { \
279
+ switch (sizeof(*__gu_ptr)) { \
280
+ case 1: \
281
+ __put_user_asm("sb", (x), __gu_ptr, __pu_err); \
282
+ break; \
283
+ case 2: \
284
+ __put_user_asm("sh", (x), __gu_ptr, __pu_err); \
285
+ break; \
286
+ case 4: \
287
+ __put_user_asm("sw", (x), __gu_ptr, __pu_err); \
288
+ break; \
289
+ case 8: \
290
+ __put_user_8((x), __gu_ptr, __pu_err); \
291
+ break; \
292
+ default: \
293
+ BUILD_BUG(); \
294
+ } \
295
+ } while (0)
319
296
320
297
/**
321
298
* __put_user: - Write a simple value into user space, with less checking.
@@ -338,25 +315,15 @@ do { \
338
315
*/
339
316
#define __put_user (x , ptr ) \
340
317
({ \
341
- register long __pu_err = 0; \
342
318
__typeof__(*(ptr)) __user *__gu_ptr = (ptr); \
319
+ long __pu_err = 0; \
320
+ \
343
321
__chk_user_ptr(__gu_ptr); \
344
- switch (sizeof(*__gu_ptr)) { \
345
- case 1: \
346
- __put_user_asm("sb", (x), __gu_ptr, __pu_err); \
347
- break; \
348
- case 2: \
349
- __put_user_asm("sh", (x), __gu_ptr, __pu_err); \
350
- break; \
351
- case 4: \
352
- __put_user_asm("sw", (x), __gu_ptr, __pu_err); \
353
- break; \
354
- case 8: \
355
- __put_user_8((x), __gu_ptr, __pu_err); \
356
- break; \
357
- default: \
358
- BUILD_BUG(); \
359
- } \
322
+ \
323
+ __enable_user_access(); \
324
+ __put_user_nocheck(x, __gu_ptr, __pu_err); \
325
+ __disable_user_access(); \
326
+ \
360
327
__pu_err; \
361
328
})
362
329
@@ -385,6 +352,24 @@ do { \
385
352
-EFAULT; \
386
353
})
387
354
355
+
356
+ unsigned long __must_check __asm_copy_to_user (void __user * to ,
357
+ const void * from , unsigned long n );
358
+ unsigned long __must_check __asm_copy_from_user (void * to ,
359
+ const void __user * from , unsigned long n );
360
+
361
+ static inline unsigned long
362
+ raw_copy_from_user (void * to , const void __user * from , unsigned long n )
363
+ {
364
+ return __asm_copy_from_user (to , from , n );
365
+ }
366
+
367
+ static inline unsigned long
368
+ raw_copy_to_user (void __user * to , const void * from , unsigned long n )
369
+ {
370
+ return __asm_copy_to_user (to , from , n );
371
+ }
372
+
388
373
extern long strncpy_from_user (char * dest , const char __user * src , long count );
389
374
390
375
extern long __must_check strlen_user (const char __user * str );
@@ -476,6 +461,26 @@ unsigned long __must_check clear_user(void __user *to, unsigned long n)
476
461
__ret; \
477
462
})
478
463
464
+ #define HAVE_GET_KERNEL_NOFAULT
465
+
466
+ #define __get_kernel_nofault (dst , src , type , err_label ) \
467
+ do { \
468
+ long __kr_err; \
469
+ \
470
+ __get_user_nocheck(*((type *)(dst)), (type *)(src), __kr_err); \
471
+ if (unlikely(__kr_err)) \
472
+ goto err_label; \
473
+ } while (0)
474
+
475
+ #define __put_kernel_nofault (dst , src , type , err_label ) \
476
+ do { \
477
+ long __kr_err; \
478
+ \
479
+ __put_user_nocheck(*((type *)(dst)), (type *)(src), __kr_err); \
480
+ if (unlikely(__kr_err)) \
481
+ goto err_label; \
482
+ } while (0)
483
+
479
484
#else /* CONFIG_MMU */
480
485
#include <asm-generic/uaccess.h>
481
486
#endif /* CONFIG_MMU */
0 commit comments