uaccess.h

来自「Linux Kernel 2.6.9 for OMAP1710」· C头文件 代码 · 共 506 行 · 第 1/2 页

H
506
字号
({								\	long __pu_err;						\	__put_user_size((x),(ptr),(size),__pu_err,-EFAULT);	\	__pu_err;						\})#define __put_user_check(x,ptr,size)					\({									\	long __pu_err = -EFAULT;					\	__typeof__(*(ptr)) __user *__pu_addr = (ptr);			\	might_sleep();						\	if (access_ok(VERIFY_WRITE,__pu_addr,size))			\		__put_user_size((x),__pu_addr,(size),__pu_err,-EFAULT);	\	__pu_err;							\})							#define __put_user_u64(x, addr, err)				\	__asm__ __volatile__(					\		"1:	movl %%eax,0(%2)\n"			\		"2:	movl %%edx,4(%2)\n"			\		"3:\n"						\		".section .fixup,\"ax\"\n"			\		"4:	movl %3,%0\n"				\		"	jmp 3b\n"				\		".previous\n"					\		".section __ex_table,\"a\"\n"			\		"	.align 4\n"				\		"	.long 1b,4b\n"				\		"	.long 2b,4b\n"				\		".previous"					\		: "=r"(err)					\		: "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))#ifdef CONFIG_X86_WP_WORKS_OK#define __put_user_size(x,ptr,size,retval,errret)			\do {									\	retval = 0;							\	__chk_user_ptr(ptr);						\	switch (size) {							\	case 1: __put_user_asm(x,ptr,retval,"b","b","iq",errret);break;	\	case 2: __put_user_asm(x,ptr,retval,"w","w","ir",errret);break; \	case 4: __put_user_asm(x,ptr,retval,"l","","ir",errret); break;	\	case 8: __put_user_u64((__typeof__(*ptr))(x),ptr,retval); break;\	  default: __put_user_bad();					\	}								\} while (0)#else#define __put_user_size(x,ptr,size,retval,errret)			\do {									\	__typeof__(*(ptr)) __pus_tmp = x;				\	retval = 0;							\									\	if(unlikely(__copy_to_user_ll(ptr, &__pus_tmp, size) != 0))	\		retval = errret;					\} while (0)#endifstruct __large_struct { unsigned long buf[100]; };#define __m(x) (*(struct __large_struct *)(x))/* * Tell gcc we read from memory instead of writing: this is because * we do not write to any memory gcc knows about, so there are no * aliasing issues. */#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret)	\	__asm__ __volatile__(						\		"1:	mov"itype" %"rtype"1,%2\n"			\		"2:\n"							\		".section .fixup,\"ax\"\n"				\		"3:	movl %3,%0\n"					\		"	jmp 2b\n"					\		".previous\n"						\		".section __ex_table,\"a\"\n"				\		"	.align 4\n"					\		"	.long 1b,3b\n"					\		".previous"						\		: "=r"(err)						\		: ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))#define __get_user_nocheck(x,ptr,size)				\({								\	long __gu_err, __gu_val;				\	__get_user_size(__gu_val,(ptr),(size),__gu_err,-EFAULT);\	(x) = (__typeof__(*(ptr)))__gu_val;			\	__gu_err;						\})extern long __get_user_bad(void);#define __get_user_size(x,ptr,size,retval,errret)			\do {									\	retval = 0;							\	__chk_user_ptr(ptr);						\	switch (size) {							\	case 1: __get_user_asm(x,ptr,retval,"b","b","=q",errret);break;	\	case 2: __get_user_asm(x,ptr,retval,"w","w","=r",errret);break;	\	case 4: __get_user_asm(x,ptr,retval,"l","","=r",errret);break;	\	default: (x) = __get_user_bad();				\	}								\} while (0)#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret)	\	__asm__ __volatile__(						\		"1:	mov"itype" %2,%"rtype"1\n"			\		"2:\n"							\		".section .fixup,\"ax\"\n"				\		"3:	movl %3,%0\n"					\		"	xor"itype" %"rtype"1,%"rtype"1\n"		\		"	jmp 2b\n"					\		".previous\n"						\		".section __ex_table,\"a\"\n"				\		"	.align 4\n"					\		"	.long 1b,3b\n"					\		".previous"						\		: "=r"(err), ltype (x)					\		: "m"(__m(addr)), "i"(errret), "0"(err))unsigned long __must_check __copy_to_user_ll(void __user *to,				const void *from, unsigned long n);unsigned long __must_check __copy_from_user_ll(void *to,				const void __user *from, unsigned long n);/* * Here we special-case 1, 2 and 4-byte copy_*_user invocations.  On a fault * we return the initial request size (1, 2 or 4), as copy_*_user should do. * If a store crosses a page boundary and gets a fault, the x86 will not write * anything, so this is accurate. *//** * __copy_to_user: - Copy a block of data into user space, with less checking. * @to:   Destination address, in user space. * @from: Source address, in kernel space. * @n:    Number of bytes to copy. * * Context: User context only.  This function may sleep. * * Copy data from kernel space to user space.  Caller must check * the specified block with access_ok() before calling this function. * * Returns number of bytes that could not be copied. * On success, this will be zero. */static inline unsigned long __must_check__copy_to_user_inatomic(void __user *to, const void *from, unsigned long n){	if (__builtin_constant_p(n)) {		unsigned long ret;		switch (n) {		case 1:			__put_user_size(*(u8 *)from, (u8 __user *)to, 1, ret, 1);			return ret;		case 2:			__put_user_size(*(u16 *)from, (u16 __user *)to, 2, ret, 2);			return ret;		case 4:			__put_user_size(*(u32 *)from, (u32 __user *)to, 4, ret, 4);			return ret;		}	}	return __copy_to_user_ll(to, from, n);}static inline unsigned long __must_check__copy_to_user(void __user *to, const void *from, unsigned long n){       might_sleep();       return __copy_to_user_inatomic(to, from, n);}/** * __copy_from_user: - Copy a block of data from user space, with less checking. * @to:   Destination address, in kernel space. * @from: Source address, in user space. * @n:    Number of bytes to copy. * * Context: User context only.  This function may sleep. * * Copy data from user space to kernel space.  Caller must check * the specified block with access_ok() before calling this function. * * Returns number of bytes that could not be copied. * On success, this will be zero. * * If some data could not be copied, this function will pad the copied * data to the requested size using zero bytes. */static inline unsigned long__copy_from_user_inatomic(void *to, const void __user *from, unsigned long n){	if (__builtin_constant_p(n)) {		unsigned long ret;		switch (n) {		case 1:			__get_user_size(*(u8 *)to, from, 1, ret, 1);			return ret;		case 2:			__get_user_size(*(u16 *)to, from, 2, ret, 2);			return ret;		case 4:			__get_user_size(*(u32 *)to, from, 4, ret, 4);			return ret;		}	}	return __copy_from_user_ll(to, from, n);}static inline unsigned long__copy_from_user(void *to, const void __user *from, unsigned long n){       might_sleep();       return __copy_from_user_inatomic(to, from, n);}unsigned long __must_check copy_to_user(void __user *to,				const void *from, unsigned long n);unsigned long __must_check copy_from_user(void *to,				const void __user *from, unsigned long n);long __must_check strncpy_from_user(char *dst, const char __user *src,				long count);long __must_check __strncpy_from_user(char *dst,				const char __user *src, long count);/** * strlen_user: - Get the size of a string in user space. * @str: The string to measure. * * Context: User context only.  This function may sleep. * * Get the size of a NUL-terminated string in user space. * * Returns the size of the string INCLUDING the terminating NUL. * On exception, returns 0. * * If there is a limit on the length of a valid string, you may wish to * consider using strnlen_user() instead. */#define strlen_user(str) strnlen_user(str, ~0UL >> 1)long strnlen_user(const char __user *str, long n);unsigned long __must_check clear_user(void __user *mem, unsigned long len);unsigned long __must_check __clear_user(void __user *mem, unsigned long len);#endif /* __i386_UACCESS_H */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?