X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=include%2Fasm-x86_64%2Fuaccess.h;h=bddffcb591b8b26c1068292c459d3d1ae446350b;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=ba3d49d8a888a73cdf5e4d2a187a0c75b4623dc3;hpb=9bf4aaab3e101692164d49b7ca357651eb691cb6;p=linux-2.6.git diff --git a/include/asm-x86_64/uaccess.h b/include/asm-x86_64/uaccess.h index ba3d49d8a..bddffcb59 100644 --- a/include/asm-x86_64/uaccess.h +++ b/include/asm-x86_64/uaccess.h @@ -49,12 +49,6 @@ #define access_ok(type, addr, size) (__range_not_ok(addr,size) == 0) -extern inline int verify_area(int type, const void __user * addr, unsigned long size) -{ - return access_ok(type,addr,size) ? 0 : -EFAULT; -} - - /* * The exception table consists of pairs of addresses: the first is the * address of an instruction that is allowed to fault, and the second is @@ -73,6 +67,7 @@ struct exception_table_entry unsigned long insn, fixup; }; +#define ARCH_HAS_SEARCH_EXTABLE /* * These are the main single-value transfer routines. They automatically @@ -89,20 +84,15 @@ struct exception_table_entry * accesses to the same area of user memory). */ -extern void __get_user_1(void); -extern void __get_user_2(void); -extern void __get_user_4(void); -extern void __get_user_8(void); - #define __get_user_x(size,ret,x,ptr) \ __asm__ __volatile__("call __get_user_" #size \ :"=a" (ret),"=d" (x) \ - :"0" (ptr) \ - :"rbx") + :"c" (ptr) \ + :"r8") /* Careful: we have to cast the result to the type of the pointer for sign reasons */ #define get_user(x,ptr) \ -({ long __val_gu; \ +({ unsigned long __val_gu; \ int __ret_gu; \ __chk_user_ptr(ptr); \ switch(sizeof (*(ptr))) { \ @@ -120,14 +110,13 @@ extern void __put_user_1(void); extern void __put_user_2(void); extern void __put_user_4(void); extern void __put_user_8(void); - extern void __put_user_bad(void); #define __put_user_x(size,ret,x,ptr) \ __asm__ __volatile__("call __put_user_" #size \ :"=a" (ret) \ - :"0" (ptr),"d" (x) \ - :"rbx") + :"c" (ptr),"d" (x) \ + :"r8") #define put_user(x,ptr) \ __put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) @@ -137,6 +126,9 @@ extern void __put_user_bad(void); #define __put_user(x,ptr) \ __put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr))) +#define __get_user_unaligned __get_user +#define __put_user_unaligned __put_user + #define __put_user_nocheck(x,ptr,size) \ ({ \ int __pu_err; \ @@ -147,10 +139,15 @@ extern void __put_user_bad(void); #define __put_user_check(x,ptr,size) \ ({ \ - int __pu_err = -EFAULT; \ + int __pu_err; \ __typeof__(*(ptr)) __user *__pu_addr = (ptr); \ - if (likely(access_ok(VERIFY_WRITE,__pu_addr,size))) \ - __put_user_size((x),__pu_addr,(size),__pu_err); \ + switch (size) { \ + case 1: __put_user_x(1,__pu_err,x,__pu_addr); break; \ + case 2: __put_user_x(2,__pu_err,x,__pu_addr); break; \ + case 4: __put_user_x(4,__pu_err,x,__pu_addr); break; \ + case 8: __put_user_x(8,__pu_err,x,__pu_addr); break; \ + default: __put_user_bad(); \ + } \ __pu_err; \ }) @@ -169,7 +166,7 @@ do { \ /* FIXME: this hack is definitely wrong -AK */ struct __large_struct { unsigned long buf[100]; }; -#define __m(x) (*(struct __large_struct *)(x)) +#define __m(x) (*(struct __large_struct __user *)(x)) /* * Tell gcc we read from memory instead of writing: this is because @@ -195,12 +192,16 @@ struct __large_struct { unsigned long buf[100]; }; #define __get_user_nocheck(x,ptr,size) \ ({ \ int __gu_err; \ - long __gu_val; \ + unsigned long __gu_val; \ __get_user_size(__gu_val,(ptr),(size),__gu_err); \ (x) = (__typeof__(*(ptr)))__gu_val; \ __gu_err; \ }) +extern int __get_user_1(void); +extern int __get_user_2(void); +extern int __get_user_4(void); +extern int __get_user_8(void); extern int __get_user_bad(void); #define __get_user_size(x,ptr,size,retval) \ @@ -243,7 +244,7 @@ extern unsigned long copy_to_user(void __user *to, const void *from, unsigned le extern unsigned long copy_from_user(void *to, const void __user *from, unsigned len); extern unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len); -static inline int __copy_from_user(void *dst, const void __user *src, unsigned size) +static __always_inline int __copy_from_user(void *dst, const void __user *src, unsigned size) { int ret = 0; if (!__builtin_constant_p(size)) @@ -272,7 +273,7 @@ static inline int __copy_from_user(void *dst, const void __user *src, unsigned s } } -static inline int __copy_to_user(void __user *dst, const void *src, unsigned size) +static __always_inline int __copy_to_user(void __user *dst, const void *src, unsigned size) { int ret = 0; if (!__builtin_constant_p(size)) @@ -304,7 +305,7 @@ static inline int __copy_to_user(void __user *dst, const void *src, unsigned siz } -static inline int __copy_in_user(void __user *dst, const void __user *src, unsigned size) +static __always_inline int __copy_in_user(void __user *dst, const void __user *src, unsigned size) { int ret = 0; if (!__builtin_constant_p(size)) @@ -347,8 +348,12 @@ static inline int __copy_in_user(void __user *dst, const void __user *src, unsig long strncpy_from_user(char *dst, const char __user *src, long count); long __strncpy_from_user(char *dst, const char __user *src, long count); long strnlen_user(const char __user *str, long n); +long __strnlen_user(const char __user *str, long n); long strlen_user(const char __user *str); unsigned long clear_user(void __user *mem, unsigned long len); unsigned long __clear_user(void __user *mem, unsigned long len); +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + #endif /* __X86_64_UACCESS_H */