~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/include/asm-arm/uaccess.h

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #ifndef _ASMARM_UACCESS_H
  2 #define _ASMARM_UACCESS_H
  3 
  4 /*
  5  * User space memory access functions
  6  */
  7 #include <linux/sched.h>
  8 #include <asm/errno.h>
  9 
 10 #define VERIFY_READ 0
 11 #define VERIFY_WRITE 1
 12 
 13 /*
 14  * The exception table consists of pairs of addresses: the first is the
 15  * address of an instruction that is allowed to fault, and the second is
 16  * the address at which the program should continue.  No registers are
 17  * modified, so it is entirely up to the continuation code to figure out
 18  * what to do.
 19  *
 20  * All the routines below use bits of fixup code that are out of line
 21  * with the main instruction path.  This means when everything is well,
 22  * we don't even have to jump over them.  Further, they do not intrude
 23  * on our cache or tlb entries.
 24  */
 25 
 26 struct exception_table_entry
 27 {
 28         unsigned long insn, fixup;
 29 };
 30 
 31 /* Returns 0 if exception not found and fixup otherwise.  */
 32 extern unsigned long search_exception_table(unsigned long);
 33 
 34 #define get_ds()        (KERNEL_DS)
 35 #define get_fs()        (current->addr_limit)
 36 #define segment_eq(a,b) ((a) == (b))
 37 
 38 #include <asm/proc/uaccess.h>
 39 
 40 #define access_ok(type,addr,size)       (__range_ok(addr,size) == 0)
 41 
 42 extern __inline__ int verify_area(int type, const void * addr, unsigned long size)
 43 {
 44         return access_ok(type, addr, size) ? 0 : -EFAULT;
 45 }
 46 
 47 /*
 48  * Single-value transfer routines.  They automatically use the right
 49  * size if we just have the right pointer type.  Note that the functions
 50  * which read from user space (*get_*) need to take care not to leak
 51  * kernel data even if the calling code is buggy and fails to check
 52  * the return value.  This means zeroing out the destination variable
 53  * or buffer on error.  Normally this is done out of line by the
 54  * fixup code, but there are a few places where it intrudes on the
 55  * main code path.  When we only write to user space, there is no
 56  * problem.
 57  *
 58  * The "__xxx" versions of the user access functions do not verify the
 59  * address space - it must have been done previously with a separate
 60  * "access_ok()" call.
 61  *
 62  * The "xxx_error" versions set the third argument to EFAULT if an
 63  * error occurs, and leave it unchanged on success.  Note that these
 64  * versions are void (ie, don't return a value as such).
 65  */
 66 #define get_user(x,p)           __get_user_check((x),(p),sizeof(*(p)))
 67 #define __get_user(x,p)         __get_user_nocheck((x),(p),sizeof(*(p)))
 68 #define __get_user_error(x,p,e) __get_user_nocheck_error((x),(p),sizeof(*(p)),(e))
 69 
 70 #define put_user(x,p)           __put_user_check((__typeof(*(p)))(x),(p),sizeof(*(p)))
 71 #define __put_user(x,p)         __put_user_nocheck((__typeof(*(p)))(x),(p),sizeof(*(p)))
 72 #define __put_user_error(x,p,e) __put_user_nocheck_error((x),(p),sizeof(*(p)),(e))
 73 
 74 static __inline__ unsigned long copy_from_user(void *to, const void *from, unsigned long n)
 75 {
 76         if (access_ok(VERIFY_READ, from, n))
 77                 __do_copy_from_user(to, from, n);
 78         return n;
 79 }
 80 
 81 static __inline__ unsigned long __copy_from_user(void *to, const void *from, unsigned long n)
 82 {
 83         __do_copy_from_user(to, from, n);
 84         return n;
 85 }
 86 
 87 static __inline__ unsigned long copy_to_user(void *to, const void *from, unsigned long n)
 88 {
 89         if (access_ok(VERIFY_WRITE, to, n))
 90                 __do_copy_to_user(to, from, n);
 91         return n;
 92 }
 93 
 94 static __inline__ unsigned long __copy_to_user(void *to, const void *from, unsigned long n)
 95 {
 96         __do_copy_to_user(to, from, n);
 97         return n;
 98 }
 99 
100 static __inline__ unsigned long clear_user (void *to, unsigned long n)
101 {
102         if (access_ok(VERIFY_WRITE, to, n))
103                 __do_clear_user(to, n);
104         return n;
105 }
106 
107 static __inline__ unsigned long __clear_user (void *to, unsigned long n)
108 {
109         __do_clear_user(to, n);
110         return n;
111 }
112 
113 static __inline__ long strncpy_from_user (char *dst, const char *src, long count)
114 {
115         long res = -EFAULT;
116         if (access_ok(VERIFY_READ, src, 1))
117                 __do_strncpy_from_user(dst, src, count, res);
118         return res;
119 }
120 
121 static __inline__ long __strncpy_from_user (char *dst, const char *src, long count)
122 {
123         long res;
124         __do_strncpy_from_user(dst, src, count, res);
125         return res;
126 }
127 
128 #define strlen_user(s)  strnlen_user(s, ~0UL >> 1)
129 
130 extern __inline__ long strnlen_user(const char *s, long n)
131 {
132         unsigned long res = 0;
133 
134         if (__addr_ok(s))
135                 __do_strnlen_user(s, n, res);
136 
137         return res;
138 }
139 
140 /*
141  * These are the work horses of the get/put_user functions
142  */
143 #define __get_user_check(x,ptr,size)                                    \
144 ({                                                                      \
145         long __gu_err = -EFAULT, __gu_val = 0;                          \
146         const __typeof__(*(ptr)) *__gu_addr = (ptr);                    \
147         if (access_ok(VERIFY_READ,__gu_addr,size)) {                    \
148                 __gu_err = 0;                                           \
149                 __get_user_size(__gu_val,__gu_addr,(size),__gu_err);    \
150         }                                                               \
151         (x) = (__typeof__(*(ptr)))__gu_val;                             \
152         __gu_err;                                                       \
153 })
154 
155 #define __get_user_nocheck(x,ptr,size)                                  \
156 ({                                                                      \
157         long __gu_err = 0, __gu_val;                                    \
158         __get_user_size(__gu_val,(ptr),(size),__gu_err);                \
159         (x) = (__typeof__(*(ptr)))__gu_val;                             \
160         __gu_err;                                                       \
161 })
162 
163 #define __get_user_nocheck_error(x,ptr,size,err)                        \
164 ({                                                                      \
165         long __gu_val;                                                  \
166         __get_user_size(__gu_val,(ptr),(size),(err));                   \
167         (x) = (__typeof__(*(ptr)))__gu_val;                             \
168         (void) 0;                                                       \
169 })
170 
171 #define __put_user_check(x,ptr,size)                                    \
172 ({                                                                      \
173         long __pu_err = -EFAULT;                                        \
174         __typeof__(*(ptr)) *__pu_addr = (ptr);                          \
175         if (access_ok(VERIFY_WRITE,__pu_addr,size)) {                   \
176                 __pu_err = 0;                                           \
177                 __put_user_size((x),__pu_addr,(size),__pu_err);         \
178         }                                                               \
179         __pu_err;                                                       \
180 })
181 
182 #define __put_user_nocheck(x,ptr,size)                                  \
183 ({                                                                      \
184         long __pu_err = 0;                                              \
185         __put_user_size((x),(ptr),(size),__pu_err);                     \
186         __pu_err;                                                       \
187 })
188 
189 #define __put_user_nocheck_error(x,ptr,size,err)                        \
190 ({                                                                      \
191         __put_user_size((x),(ptr),(size),err);                          \
192         (void) 0;                                                       \
193 })
194 
195 extern long __get_user_bad(void);
196 
197 #define __get_user_size(x,ptr,size,retval)                              \
198 do {                                                                    \
199         switch (size) {                                                 \
200         case 1: __get_user_asm_byte(x,ptr,retval);      break;          \
201         case 2: __get_user_asm_half(x,ptr,retval);      break;          \
202         case 4: __get_user_asm_word(x,ptr,retval);      break;          \
203         default: (x) = __get_user_bad();                                \
204         }                                                               \
205 } while (0)
206 
207 extern long __put_user_bad(void);
208 
209 #define __put_user_size(x,ptr,size,retval)                              \
210 do {                                                                    \
211         switch (size) {                                                 \
212         case 1: __put_user_asm_byte(x,ptr,retval);      break;          \
213         case 2: __put_user_asm_half(x,ptr,retval);      break;          \
214         case 4: __put_user_asm_word(x,ptr,retval);      break;          \
215         default: __put_user_bad();                                      \
216         }                                                               \
217 } while (0)
218 
219 #endif /* _ASMARM_UACCESS_H */
220 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.