1313/*
1414 * User space memory access functions
1515 */
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-
3416#ifdef CONFIG_MMU
3517#include <linux/errno.h>
3618#include <linux/compiler.h>
@@ -44,29 +26,6 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n)
4426#define __disable_user_access () \
4527 __asm__ __volatile__ ("csrc sstatus, %0" : : "r" (SR_SUM) : "memory")
4628
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-
7029/**
7130 * access_ok: - Checks if a user space pointer is valid
7231 * @addr: User space pointer to start of block to check
@@ -94,9 +53,7 @@ static inline void set_fs(mm_segment_t fs)
9453 */
9554static inline int __access_ok (unsigned long addr , unsigned long size )
9655{
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 ;
10057}
10158
10259/*
@@ -125,7 +82,6 @@ static inline int __access_ok(unsigned long addr, unsigned long size)
12582do { \
12683 uintptr_t __tmp; \
12784 __typeof__(x) __x; \
128- __enable_user_access(); \
12985 __asm__ __volatile__ ( \
13086 "1:\n" \
13187 " " insn " %1, %3\n" \
@@ -143,7 +99,6 @@ do { \
14399 " .previous" \
144100 : "+r" (err), "=&r" (__x), "=r" (__tmp) \
145101 : "m" (*(ptr)), "i" (-EFAULT)); \
146- __disable_user_access(); \
147102 (x) = __x; \
148103} while (0)
149104
@@ -156,7 +111,6 @@ do { \
156111 u32 __user *__ptr = (u32 __user *)(ptr); \
157112 u32 __lo, __hi; \
158113 uintptr_t __tmp; \
159- __enable_user_access(); \
160114 __asm__ __volatile__ ( \
161115 "1:\n" \
162116 " lw %1, %4\n" \
@@ -180,12 +134,30 @@ do { \
180134 "=r" (__tmp) \
181135 : "m" (__ptr[__LSW]), "m" (__ptr[__MSW]), \
182136 "i" (-EFAULT)); \
183- __disable_user_access(); \
184137 (x) = (__typeof__(x))((__typeof__((x)-(x)))( \
185138 (((u64)__hi << 32) | __lo))); \
186139} while (0)
187140#endif /* CONFIG_64BIT */
188141
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)
189161
190162/**
191163 * __get_user: - Get a simple variable from user space, with less checking.
@@ -209,25 +181,15 @@ do { \
209181 */
210182#define __get_user (x , ptr ) \
211183({ \
212- register long __gu_err = 0; \
213184 const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \
185+ long __gu_err = 0; \
186+ \
214187 __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+ \
231193 __gu_err; \
232194})
233195
@@ -261,7 +223,6 @@ do { \
261223do { \
262224 uintptr_t __tmp; \
263225 __typeof__(*(ptr)) __x = x; \
264- __enable_user_access(); \
265226 __asm__ __volatile__ ( \
266227 "1:\n" \
267228 " " insn " %z3, %2\n" \
@@ -278,7 +239,6 @@ do { \
278239 " .previous" \
279240 : "+r" (err), "=r" (__tmp), "=m" (*(ptr)) \
280241 : "rJ" (__x), "i" (-EFAULT)); \
281- __disable_user_access(); \
282242} while (0)
283243
284244#ifdef CONFIG_64BIT
@@ -290,7 +250,6 @@ do { \
290250 u32 __user *__ptr = (u32 __user *)(ptr); \
291251 u64 __x = (__typeof__((x)-(x)))(x); \
292252 uintptr_t __tmp; \
293- __enable_user_access(); \
294253 __asm__ __volatile__ ( \
295254 "1:\n" \
296255 " sw %z4, %2\n" \
@@ -312,10 +271,28 @@ do { \
312271 "=m" (__ptr[__LSW]), \
313272 "=m" (__ptr[__MSW]) \
314273 : "rJ" (__x), "rJ" (__x >> 32), "i" (-EFAULT)); \
315- __disable_user_access(); \
316274} while (0)
317275#endif /* CONFIG_64BIT */
318276
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)
319296
320297/**
321298 * __put_user: - Write a simple value into user space, with less checking.
@@ -338,25 +315,15 @@ do { \
338315 */
339316#define __put_user (x , ptr ) \
340317({ \
341- register long __pu_err = 0; \
342318 __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \
319+ long __pu_err = 0; \
320+ \
343321 __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+ \
360327 __pu_err; \
361328})
362329
@@ -385,6 +352,24 @@ do { \
385352 -EFAULT; \
386353})
387354
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+
388373extern long strncpy_from_user (char * dest , const char __user * src , long count );
389374
390375extern 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)
476461 __ret; \
477462})
478463
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+
479484#else /* CONFIG_MMU */
480485#include <asm-generic/uaccess.h>
481486#endif /* CONFIG_MMU */
0 commit comments