uaccess.h revision 556dcee7b829e5c350c3ffdbdb87a8b15aa3c5d3
1/* 2 * Authors: Bjorn Wesen (bjornw@axis.com) 3 * Hans-Peter Nilsson (hp@axis.com) 4 */ 5 6/* Asm:s have been tweaked (within the domain of correctness) to give 7 satisfactory results for "gcc version 2.96 20000427 (experimental)". 8 9 Check regularly... 10 11 Register $r9 is chosen for temporaries, being a call-clobbered register 12 first in line to be used (notably for local blocks), not colliding with 13 parameter registers. */ 14 15#ifndef _CRIS_UACCESS_H 16#define _CRIS_UACCESS_H 17 18#ifndef __ASSEMBLY__ 19#include <linux/sched.h> 20#include <linux/errno.h> 21#include <asm/processor.h> 22#include <asm/page.h> 23 24#define VERIFY_READ 0 25#define VERIFY_WRITE 1 26 27/* 28 * The fs value determines whether argument validity checking should be 29 * performed or not. If get_fs() == USER_DS, checking is performed, with 30 * get_fs() == KERNEL_DS, checking is bypassed. 31 * 32 * For historical reasons, these macros are grossly misnamed. 33 */ 34 35#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) 36 37/* addr_limit is the maximum accessible address for the task. we misuse 38 * the KERNEL_DS and USER_DS values to both assign and compare the 39 * addr_limit values through the equally misnamed get/set_fs macros. 40 * (see above) 41 */ 42 43#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) 44#define USER_DS MAKE_MM_SEG(TASK_SIZE) 45 46#define get_ds() (KERNEL_DS) 47#define get_fs() (current_thread_info()->addr_limit) 48#define set_fs(x) (current_thread_info()->addr_limit = (x)) 49 50#define segment_eq(a,b) ((a).seg == (b).seg) 51 52#define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) 53#define __user_ok(addr,size) (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size))) 54#define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size))) 55#define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size)) 56 57#include <arch/uaccess.h> 58 59/* 60 * The exception table consists of pairs of addresses: the first is the 61 * address of an instruction that is allowed to fault, and the second is 62 * the address at which the program should continue. No registers are 63 * modified, so it is entirely up to the continuation code to figure out 64 * what to do. 65 * 66 * All the routines below use bits of fixup code that are out of line 67 * with the main instruction path. This means when everything is well, 68 * we don't even have to jump over them. Further, they do not intrude 69 * on our cache or tlb entries. 70 */ 71 72struct exception_table_entry 73{ 74 unsigned long insn, fixup; 75}; 76 77/* 78 * These are the main single-value transfer routines. They automatically 79 * use the right size if we just have the right pointer type. 80 * 81 * This gets kind of ugly. We want to return _two_ values in "get_user()" 82 * and yet we don't want to do any pointers, because that is too much 83 * of a performance impact. Thus we have a few rather ugly macros here, 84 * and hide all the ugliness from the user. 85 * 86 * The "__xxx" versions of the user access functions are versions that 87 * do not verify the address space, that must have been done previously 88 * with a separate "access_ok()" call (this is used when we do multiple 89 * accesses to the same area of user memory). 90 * 91 * As we use the same address space for kernel and user data on 92 * CRIS, we can just do these as direct assignments. (Of course, the 93 * exception handling means that it's no longer "just"...) 94 */ 95#define get_user(x,ptr) \ 96 __get_user_check((x),(ptr),sizeof(*(ptr))) 97#define put_user(x,ptr) \ 98 __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) 99 100#define __get_user(x,ptr) \ 101 __get_user_nocheck((x),(ptr),sizeof(*(ptr))) 102#define __put_user(x,ptr) \ 103 __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) 104 105extern long __put_user_bad(void); 106 107#define __put_user_size(x,ptr,size,retval) \ 108do { \ 109 retval = 0; \ 110 switch (size) { \ 111 case 1: __put_user_asm(x,ptr,retval,"move.b"); break; \ 112 case 2: __put_user_asm(x,ptr,retval,"move.w"); break; \ 113 case 4: __put_user_asm(x,ptr,retval,"move.d"); break; \ 114 case 8: __put_user_asm_64(x,ptr,retval); break; \ 115 default: __put_user_bad(); \ 116 } \ 117} while (0) 118 119#define __get_user_size(x,ptr,size,retval) \ 120do { \ 121 retval = 0; \ 122 switch (size) { \ 123 case 1: __get_user_asm(x,ptr,retval,"move.b"); break; \ 124 case 2: __get_user_asm(x,ptr,retval,"move.w"); break; \ 125 case 4: __get_user_asm(x,ptr,retval,"move.d"); break; \ 126 case 8: __get_user_asm_64(x,ptr,retval); break; \ 127 default: (x) = __get_user_bad(); \ 128 } \ 129} while (0) 130 131#define __put_user_nocheck(x,ptr,size) \ 132({ \ 133 long __pu_err; \ 134 __put_user_size((x),(ptr),(size),__pu_err); \ 135 __pu_err; \ 136}) 137 138#define __put_user_check(x,ptr,size) \ 139({ \ 140 long __pu_err = -EFAULT; \ 141 __typeof__(*(ptr)) *__pu_addr = (ptr); \ 142 if (access_ok(VERIFY_WRITE,__pu_addr,size)) \ 143 __put_user_size((x),__pu_addr,(size),__pu_err); \ 144 __pu_err; \ 145}) 146 147struct __large_struct { unsigned long buf[100]; }; 148#define __m(x) (*(struct __large_struct *)(x)) 149 150 151 152#define __get_user_nocheck(x,ptr,size) \ 153({ \ 154 long __gu_err, __gu_val; \ 155 __get_user_size(__gu_val,(ptr),(size),__gu_err); \ 156 (x) = (__typeof__(*(ptr)))__gu_val; \ 157 __gu_err; \ 158}) 159 160#define __get_user_check(x,ptr,size) \ 161({ \ 162 long __gu_err = -EFAULT, __gu_val = 0; \ 163 const __typeof__(*(ptr)) *__gu_addr = (ptr); \ 164 if (access_ok(VERIFY_READ,__gu_addr,size)) \ 165 __get_user_size(__gu_val,__gu_addr,(size),__gu_err); \ 166 (x) = (__typeof__(*(ptr)))__gu_val; \ 167 __gu_err; \ 168}) 169 170extern long __get_user_bad(void); 171 172/* More complex functions. Most are inline, but some call functions that 173 live in lib/usercopy.c */ 174 175extern unsigned long __copy_user(void __user *to, const void *from, unsigned long n); 176extern unsigned long __copy_user_zeroing(void *to, const void __user *from, unsigned long n); 177extern unsigned long __do_clear_user(void __user *to, unsigned long n); 178 179static inline unsigned long 180__generic_copy_to_user(void __user *to, const void *from, unsigned long n) 181{ 182 if (access_ok(VERIFY_WRITE, to, n)) 183 return __copy_user(to,from,n); 184 return n; 185} 186 187static inline unsigned long 188__generic_copy_from_user(void *to, const void __user *from, unsigned long n) 189{ 190 if (access_ok(VERIFY_READ, from, n)) 191 return __copy_user_zeroing(to,from,n); 192 return n; 193} 194 195static inline unsigned long 196__generic_clear_user(void __user *to, unsigned long n) 197{ 198 if (access_ok(VERIFY_WRITE, to, n)) 199 return __do_clear_user(to,n); 200 return n; 201} 202 203static inline long 204__strncpy_from_user(char *dst, const char __user *src, long count) 205{ 206 return __do_strncpy_from_user(dst, src, count); 207} 208 209static inline long 210strncpy_from_user(char *dst, const char __user *src, long count) 211{ 212 long res = -EFAULT; 213 if (access_ok(VERIFY_READ, src, 1)) 214 res = __do_strncpy_from_user(dst, src, count); 215 return res; 216} 217 218 219/* Note that these expand awfully if made into switch constructs, so 220 don't do that. */ 221 222static inline unsigned long 223__constant_copy_from_user(void *to, const void __user *from, unsigned long n) 224{ 225 unsigned long ret = 0; 226 if (n == 0) 227 ; 228 else if (n == 1) 229 __asm_copy_from_user_1(to, from, ret); 230 else if (n == 2) 231 __asm_copy_from_user_2(to, from, ret); 232 else if (n == 3) 233 __asm_copy_from_user_3(to, from, ret); 234 else if (n == 4) 235 __asm_copy_from_user_4(to, from, ret); 236 else if (n == 5) 237 __asm_copy_from_user_5(to, from, ret); 238 else if (n == 6) 239 __asm_copy_from_user_6(to, from, ret); 240 else if (n == 7) 241 __asm_copy_from_user_7(to, from, ret); 242 else if (n == 8) 243 __asm_copy_from_user_8(to, from, ret); 244 else if (n == 9) 245 __asm_copy_from_user_9(to, from, ret); 246 else if (n == 10) 247 __asm_copy_from_user_10(to, from, ret); 248 else if (n == 11) 249 __asm_copy_from_user_11(to, from, ret); 250 else if (n == 12) 251 __asm_copy_from_user_12(to, from, ret); 252 else if (n == 13) 253 __asm_copy_from_user_13(to, from, ret); 254 else if (n == 14) 255 __asm_copy_from_user_14(to, from, ret); 256 else if (n == 15) 257 __asm_copy_from_user_15(to, from, ret); 258 else if (n == 16) 259 __asm_copy_from_user_16(to, from, ret); 260 else if (n == 20) 261 __asm_copy_from_user_20(to, from, ret); 262 else if (n == 24) 263 __asm_copy_from_user_24(to, from, ret); 264 else 265 ret = __generic_copy_from_user(to, from, n); 266 267 return ret; 268} 269 270/* Ditto, don't make a switch out of this. */ 271 272static inline unsigned long 273__constant_copy_to_user(void __user *to, const void *from, unsigned long n) 274{ 275 unsigned long ret = 0; 276 if (n == 0) 277 ; 278 else if (n == 1) 279 __asm_copy_to_user_1(to, from, ret); 280 else if (n == 2) 281 __asm_copy_to_user_2(to, from, ret); 282 else if (n == 3) 283 __asm_copy_to_user_3(to, from, ret); 284 else if (n == 4) 285 __asm_copy_to_user_4(to, from, ret); 286 else if (n == 5) 287 __asm_copy_to_user_5(to, from, ret); 288 else if (n == 6) 289 __asm_copy_to_user_6(to, from, ret); 290 else if (n == 7) 291 __asm_copy_to_user_7(to, from, ret); 292 else if (n == 8) 293 __asm_copy_to_user_8(to, from, ret); 294 else if (n == 9) 295 __asm_copy_to_user_9(to, from, ret); 296 else if (n == 10) 297 __asm_copy_to_user_10(to, from, ret); 298 else if (n == 11) 299 __asm_copy_to_user_11(to, from, ret); 300 else if (n == 12) 301 __asm_copy_to_user_12(to, from, ret); 302 else if (n == 13) 303 __asm_copy_to_user_13(to, from, ret); 304 else if (n == 14) 305 __asm_copy_to_user_14(to, from, ret); 306 else if (n == 15) 307 __asm_copy_to_user_15(to, from, ret); 308 else if (n == 16) 309 __asm_copy_to_user_16(to, from, ret); 310 else if (n == 20) 311 __asm_copy_to_user_20(to, from, ret); 312 else if (n == 24) 313 __asm_copy_to_user_24(to, from, ret); 314 else 315 ret = __generic_copy_to_user(to, from, n); 316 317 return ret; 318} 319 320/* No switch, please. */ 321 322static inline unsigned long 323__constant_clear_user(void __user *to, unsigned long n) 324{ 325 unsigned long ret = 0; 326 if (n == 0) 327 ; 328 else if (n == 1) 329 __asm_clear_1(to, ret); 330 else if (n == 2) 331 __asm_clear_2(to, ret); 332 else if (n == 3) 333 __asm_clear_3(to, ret); 334 else if (n == 4) 335 __asm_clear_4(to, ret); 336 else if (n == 8) 337 __asm_clear_8(to, ret); 338 else if (n == 12) 339 __asm_clear_12(to, ret); 340 else if (n == 16) 341 __asm_clear_16(to, ret); 342 else if (n == 20) 343 __asm_clear_20(to, ret); 344 else if (n == 24) 345 __asm_clear_24(to, ret); 346 else 347 ret = __generic_clear_user(to, n); 348 349 return ret; 350} 351 352 353#define clear_user(to, n) \ 354(__builtin_constant_p(n) ? \ 355 __constant_clear_user(to, n) : \ 356 __generic_clear_user(to, n)) 357 358#define copy_from_user(to, from, n) \ 359(__builtin_constant_p(n) ? \ 360 __constant_copy_from_user(to, from, n) : \ 361 __generic_copy_from_user(to, from, n)) 362 363#define copy_to_user(to, from, n) \ 364(__builtin_constant_p(n) ? \ 365 __constant_copy_to_user(to, from, n) : \ 366 __generic_copy_to_user(to, from, n)) 367 368/* We let the __ versions of copy_from/to_user inline, because they're often 369 * used in fast paths and have only a small space overhead. 370 */ 371 372static inline unsigned long 373__generic_copy_from_user_nocheck(void *to, const void __user *from, 374 unsigned long n) 375{ 376 return __copy_user_zeroing(to,from,n); 377} 378 379static inline unsigned long 380__generic_copy_to_user_nocheck(void __user *to, const void *from, 381 unsigned long n) 382{ 383 return __copy_user(to,from,n); 384} 385 386static inline unsigned long 387__generic_clear_user_nocheck(void __user *to, unsigned long n) 388{ 389 return __do_clear_user(to,n); 390} 391 392/* without checking */ 393 394#define __copy_to_user(to,from,n) __generic_copy_to_user_nocheck((to),(from),(n)) 395#define __copy_from_user(to,from,n) __generic_copy_from_user_nocheck((to),(from),(n)) 396#define __copy_to_user_inatomic __copy_to_user 397#define __copy_from_user_inatomic __copy_from_user 398#define __clear_user(to,n) __generic_clear_user_nocheck((to),(n)) 399 400#define strlen_user(str) strnlen_user((str), 0x7ffffffe) 401 402#endif /* __ASSEMBLY__ */ 403 404#endif /* _CRIS_UACCESS_H */ 405