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 26struct exception_table_entry 27{ 28 unsigned long insn, fixup; 29}; 30 31/* Returns 0 if exception not found and fixup otherwise. */ 32extern unsigned long search_exception_table(unsigned long); 33extern int fixup_exception(struct pt_regs *regs); 34 35#define get_ds() (KERNEL_DS) 36#define get_fs() (current_thread_info()->addr_limit) 37#define segment_eq(a,b) ((a) == (b)) 38 39#include <asm/uaccess-asm.h> 40 41#define access_ok(type,addr,size) (__range_ok(addr,size) == 0) 42 43/* 44 * Single-value transfer routines. They automatically use the right 45 * size if we just have the right pointer type. Note that the functions 46 * which read from user space (*get_*) need to take care not to leak 47 * kernel data even if the calling code is buggy and fails to check 48 * the return value. This means zeroing out the destination variable 49 * or buffer on error. Normally this is done out of line by the 50 * fixup code, but there are a few places where it intrudes on the 51 * main code path. When we only write to user space, there is no 52 * problem. 53 * 54 * The "__xxx" versions of the user access functions do not verify the 55 * address space - it must have been done previously with a separate 56 * "access_ok()" call. 57 * 58 * The "xxx_error" versions set the third argument to EFAULT if an 59 * error occurs, and leave it unchanged on success. Note that these 60 * versions are void (ie, don't return a value as such). 61 */ 62 63extern int __get_user_1(void *); 64extern int __get_user_2(void *); 65extern int __get_user_4(void *); 66extern int __get_user_8(void *); 67extern int __get_user_bad(void); 68 69#define __get_user_x(__r1,__p,__e,__s,__i...) \ 70 __asm__ __volatile__ ("bl __get_user_" #__s \ 71 : "=&r" (__e), "=r" (__r1) \ 72 : "0" (__p) \ 73 : __i) 74 75#define get_user(x,p) \ 76 ({ \ 77 register const typeof(*(p)) *__p asm("r0") = (p); \ 78 register typeof(*(p)) __r1 asm("r1"); \ 79 register int __e asm("r0"); \ 80 switch (sizeof(*(p))) { \ 81 case 1: \ 82 __get_user_x(__r1, __p, __e, 1, "lr"); \ 83 break; \ 84 case 2: \ 85 __get_user_x(__r1, __p, __e, 2, "r2", "lr"); \ 86 break; \ 87 case 4: \ 88 __get_user_x(__r1, __p, __e, 4, "lr"); \ 89 break; \ 90 case 8: \ 91 __get_user_x(__r1, __p, __e, 8, "lr"); \ 92 break; \ 93 default: __e = __get_user_bad(); break; \ 94 } \ 95 x = __r1; \ 96 __e; \ 97 }) 98 99 100#define __get_user(x,ptr) \ 101({ \ 102 long __gu_err = 0; \ 103 __get_user_err((x),(ptr),__gu_err); \ 104 __gu_err; \ 105}) 106 107#define __get_user_error(x,ptr,err) \ 108({ \ 109 __get_user_err((x),(ptr),err); \ 110 (void) 0; \ 111}) 112 113#define __get_user_err(x,ptr,err) \ 114do { \ 115 unsigned long __gu_addr = (unsigned long)(ptr); \ 116 unsigned long __gu_val; \ 117 switch (sizeof(*(ptr))) { \ 118 case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \ 119 case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \ 120 case 4: __get_user_asm_word(__gu_val,__gu_addr,err); break; \ 121 default: (__gu_val) = __get_user_bad(); \ 122 } \ 123 (x) = (__typeof__(*(ptr)))__gu_val; \ 124} while (0) 125 126extern int __put_user_1(void *, unsigned int); 127extern int __put_user_2(void *, unsigned int); 128extern int __put_user_4(void *, unsigned int); 129extern int __put_user_8(void *, unsigned long long); 130extern int __put_user_bad(void); 131 132#define __put_user_x(__r1,__p,__e,__s) \ 133 __asm__ __volatile__ ( \ 134 __asmeq("%0", "r0") __asmeq("%2", "r1") \ 135 "bl __put_user_" #__s \ 136 : "=&r" (__e) \ 137 : "0" (__p), "r" (__r1) \ 138 : "ip", "lr", "cc") 139 140#define put_user(x,p) \ 141 ({ \ 142 register const typeof(*(p)) __r1 asm("r1") = (x); \ 143 register const typeof(*(p)) *__p asm("r0") = (p); \ 144 register int __e asm("r0"); \ 145 switch (sizeof(*(__p))) { \ 146 case 1: \ 147 __put_user_x(__r1, __p, __e, 1); \ 148 break; \ 149 case 2: \ 150 __put_user_x(__r1, __p, __e, 2); \ 151 break; \ 152 case 4: \ 153 __put_user_x(__r1, __p, __e, 4); \ 154 break; \ 155 case 8: \ 156 __put_user_x(__r1, __p, __e, 8); \ 157 break; \ 158 default: __e = __put_user_bad(); break; \ 159 } \ 160 __e; \ 161 }) 162 163 164#define __put_user(x,ptr) \ 165({ \ 166 long __pu_err = 0; \ 167 __put_user_err((x),(ptr),__pu_err); \ 168 __pu_err; \ 169}) 170 171#define __put_user_error(x,ptr,err) \ 172({ \ 173 __put_user_err((x),(ptr),err); \ 174 (void) 0; \ 175}) 176 177#define __put_user_err(x,ptr,err) \ 178do { \ 179 unsigned long __pu_addr = (unsigned long)(ptr); \ 180 __typeof__(*(ptr)) __pu_val = (x); \ 181 switch (sizeof(*(ptr))) { \ 182 case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \ 183 case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \ 184 case 4: __put_user_asm_word(__pu_val,__pu_addr,err); break; \ 185 case 8: __put_user_asm_dword(__pu_val,__pu_addr,err); break; \ 186 default: __put_user_bad(); \ 187 } \ 188} while (0) 189 190static __inline__ unsigned long copy_from_user(void *to, const void *from, unsigned long n) 191{ 192 if (access_ok(VERIFY_READ, from, n)) 193 __do_copy_from_user(to, from, n); 194 else /* security hole - plug it */ 195 memzero(to, n); 196 return n; 197} 198 199static __inline__ unsigned long __copy_from_user(void *to, const void *from, unsigned long n) 200{ 201 __do_copy_from_user(to, from, n); 202 return n; 203} 204 205static __inline__ unsigned long copy_to_user(void *to, const void *from, unsigned long n) 206{ 207 if (access_ok(VERIFY_WRITE, to, n)) 208 __do_copy_to_user(to, from, n); 209 return n; 210} 211 212static __inline__ unsigned long __copy_to_user(void *to, const void *from, unsigned long n) 213{ 214 __do_copy_to_user(to, from, n); 215 return n; 216} 217 218#define __copy_to_user_inatomic __copy_to_user 219#define __copy_from_user_inatomic __copy_from_user 220 221static __inline__ unsigned long clear_user (void *to, unsigned long n) 222{ 223 if (access_ok(VERIFY_WRITE, to, n)) 224 __do_clear_user(to, n); 225 return n; 226} 227 228static __inline__ unsigned long __clear_user (void *to, unsigned long n) 229{ 230 __do_clear_user(to, n); 231 return n; 232} 233 234static __inline__ long strncpy_from_user (char *dst, const char *src, long count) 235{ 236 long res = -EFAULT; 237 if (access_ok(VERIFY_READ, src, 1)) 238 __do_strncpy_from_user(dst, src, count, res); 239 return res; 240} 241 242static __inline__ long __strncpy_from_user (char *dst, const char *src, long count) 243{ 244 long res; 245 __do_strncpy_from_user(dst, src, count, res); 246 return res; 247} 248 249#define strlen_user(s) strnlen_user(s, ~0UL >> 1) 250 251static inline long strnlen_user(const char *s, long n) 252{ 253 unsigned long res = 0; 254 255 if (__addr_ok(s)) 256 __do_strnlen_user(s, n, res); 257 258 return res; 259} 260 261#endif /* _ASMARM_UACCESS_H */ 262