uaccess.h

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

H
753
字号
		".previous"						\		: "=r"(err)						\		: "r"(x), "r"(addr), "i"(-EFAULT), "0"(err)		\		: "r14", "memory")#else#error no endian defined#endif#define __put_user_size(x,ptr,size,retval)				\do {									\	retval = 0;							\	__chk_user_ptr(ptr);						\	switch (size) {							\	  case 1: __put_user_asm(x,ptr,retval,"b"); break;		\	  case 2: __put_user_asm(x,ptr,retval,"h"); break;		\	  case 4: __put_user_asm(x,ptr,retval,""); break;		\	  case 8: __put_user_u64((__typeof__(*ptr))(x),ptr,retval); break;\	  default: __put_user_bad();					\	}								\} while (0)struct __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)				\	__asm__ __volatile__(						\		"	.fillinsn\n"					\		"1:	st"itype" %1,@%2\n"				\		"	.fillinsn\n"					\		"2:\n"							\		".section .fixup,\"ax\"\n"				\		"	.balign 4\n"					\		"3:	ldi %0,%3\n"					\		"	seth r14,#high(2b)\n"				\		"	or3 r14,r14,#low(2b)\n"				\		"	jmp r14\n"					\		".previous\n"						\		".section __ex_table,\"a\"\n"				\		"	.balign 4\n"					\		"	.long 1b,3b\n"					\		".previous"						\		: "=r"(err)						\		: "r"(x), "r"(addr), "i"(-EFAULT), "0"(err)		\		: "r14", "memory")#define __get_user_nocheck(x,ptr,size)					\({									\	long __gu_err, __gu_val;					\	__get_user_size(__gu_val,(ptr),(size),__gu_err);		\	(x) = (__typeof__(*(ptr)))__gu_val;				\	__gu_err;							\})extern long __get_user_bad(void);#define __get_user_size(x,ptr,size,retval)				\do {									\	retval = 0;							\	__chk_user_ptr(ptr);						\	switch (size) {							\	  case 1: __get_user_asm(x,ptr,retval,"ub"); break;		\	  case 2: __get_user_asm(x,ptr,retval,"uh"); break;		\	  case 4: __get_user_asm(x,ptr,retval,""); break;		\	  default: (x) = __get_user_bad();				\	}								\} while (0)#define __get_user_asm(x, addr, err, itype)				\	__asm__ __volatile__(						\		"	.fillinsn\n"					\		"1:	ld"itype" %1,@%2\n"				\		"	.fillinsn\n"					\		"2:\n"							\		".section .fixup,\"ax\"\n"				\		"	.balign 4\n"					\		"3:	ldi %0,%3\n"					\		"	seth r14,#high(2b)\n"				\		"	or3 r14,r14,#low(2b)\n"				\		"	jmp r14\n"					\		".previous\n"						\		".section __ex_table,\"a\"\n"				\		"	.balign 4\n"					\		"	.long 1b,3b\n"					\		".previous"						\		: "=r"(err), "=&r"(x)					\		: "r"(addr), "i"(-EFAULT), "0"(err)			\		: "r14", "memory")/* * 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 m32r will not write * anything, so this is accurate. *//* * Copy To/From Userspace *//* Generic arbitrary sized copy.  *//* Return the number of bytes NOT copied.  */#define __copy_user(to,from,size)					\do {									\	unsigned long __dst, __src, __c;				\	__asm__ __volatile__ (						\		"	mv	r14, %0\n"				\		"	or	r14, %1\n"				\		"	beq	%0, %1, 9f\n"				\		"	beqz	%2, 9f\n"				\		"	and3	r14, r14, #3\n"				\		"	bnez	r14, 2f\n"				\		"	and3	%2, %2, #3\n"				\		"	beqz	%3, 2f\n"				\		"	addi	%0, #-4		; word_copy \n"		\		"	.fillinsn\n"					\		"0:	ld	r14, @%1+\n"				\		"	addi	%3, #-1\n"				\		"	.fillinsn\n"					\		"1:	st	r14, @+%0\n"				\		"	bnez	%3, 0b\n"				\		"	beqz	%2, 9f\n"				\		"	addi	%0, #4\n"				\		"	.fillinsn\n"					\		"2:	ldb	r14, @%1	; byte_copy \n"		\		"	.fillinsn\n"					\		"3:	stb	r14, @%0\n"				\		"	addi	%1, #1\n"				\		"	addi	%2, #-1\n"				\		"	addi	%0, #1\n"				\		"	bnez	%2, 2b\n"				\		"	.fillinsn\n"					\		"9:\n"							\		".section .fixup,\"ax\"\n"				\		"	.balign 4\n"					\		"5:	addi	%3, #1\n"				\		"	addi	%1, #-4\n"				\		"	.fillinsn\n"					\		"6:	slli	%3, #2\n"				\		"	add	%2, %3\n"				\		"	addi	%0, #4\n"				\		"	.fillinsn\n"					\		"7:	seth	r14, #high(9b)\n"			\		"	or3	r14, r14, #low(9b)\n"			\		"	jmp	r14\n"					\		".previous\n"						\		".section __ex_table,\"a\"\n"				\		"	.balign 4\n"					\		"	.long 0b,6b\n"					\		"	.long 1b,5b\n"					\		"	.long 2b,9b\n"					\		"	.long 3b,9b\n"					\		".previous\n"						\		: "=&r"(__dst), "=&r"(__src), "=&r"(size), "=&r"(__c)	\		: "0"(to), "1"(from), "2"(size), "3"(size / 4)		\		: "r14", "memory");					\} while (0)#define __copy_user_zeroing(to,from,size)				\do {									\	unsigned long __dst, __src, __c;				\	__asm__ __volatile__ (						\		"	mv	r14, %0\n"				\		"	or	r14, %1\n"				\		"	beq	%0, %1, 9f\n"				\		"	beqz	%2, 9f\n"				\		"	and3	r14, r14, #3\n"				\		"	bnez	r14, 2f\n"				\		"	and3	%2, %2, #3\n"				\		"	beqz	%3, 2f\n"				\		"	addi	%0, #-4		; word_copy \n"		\		"	.fillinsn\n"					\		"0:	ld	r14, @%1+\n"				\		"	addi	%3, #-1\n"				\		"	.fillinsn\n"					\		"1:	st	r14, @+%0\n"				\		"	bnez	%3, 0b\n"				\		"	beqz	%2, 9f\n"				\		"	addi	%0, #4\n"				\		"	.fillinsn\n"					\		"2:	ldb	r14, @%1	; byte_copy \n"		\		"	.fillinsn\n"					\		"3:	stb	r14, @%0\n"				\		"	addi	%1, #1\n"				\		"	addi	%2, #-1\n"				\		"	addi	%0, #1\n"				\		"	bnez	%2, 2b\n"				\		"	.fillinsn\n"					\		"9:\n"							\		".section .fixup,\"ax\"\n"				\		"	.balign 4\n"					\		"5:	addi	%3, #1\n"				\		"	addi	%1, #-4\n"				\		"	.fillinsn\n"					\		"6:	slli	%3, #2\n"				\		"	add	%2, %3\n"				\		"	addi	%0, #4\n"				\		"	.fillinsn\n"					\		"7:	ldi	r14, #0		; store zero \n"	\		"	.fillinsn\n"					\		"8:	addi	%2, #-1\n"				\		"	stb	r14, @%0	; ACE? \n"		\		"	addi	%0, #1\n"				\		"	bnez	%2, 8b\n"				\		"	seth	r14, #high(9b)\n"			\		"	or3	r14, r14, #low(9b)\n"			\		"	jmp	r14\n"					\		".previous\n"						\		".section __ex_table,\"a\"\n"				\		"	.balign 4\n"					\		"	.long 0b,6b\n"					\		"	.long 1b,5b\n"					\		"	.long 2b,7b\n"					\		"	.long 3b,7b\n"					\		".previous\n"						\		: "=&r"(__dst), "=&r"(__src), "=&r"(size), "=&r"(__c)	\		: "0"(to), "1"(from), "2"(size), "3"(size / 4)		\		: "r14", "memory");					\} while (0)/* We let the __ versions of copy_from/to_user inline, because they're often * used in fast paths and have only a small space overhead. */static inline unsigned long __generic_copy_from_user_nocheck(void *to,	const void __user *from, unsigned long n){	__copy_user_zeroing(to,from,n);	return n;}static inline unsigned long __generic_copy_to_user_nocheck(void __user *to,	const void *from, unsigned long n){	__copy_user(to,from,n);	return n;}unsigned long __generic_copy_to_user(void *, const void *, unsigned long);unsigned long __generic_copy_from_user(void *, const void *, unsigned long);/** * __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. */#define __copy_to_user(to,from,n)			\	__generic_copy_to_user_nocheck((to),(from),(n))#define __copy_to_user_inatomic __copy_to_user#define __copy_from_user_inatomic __copy_from_user/** * copy_to_user: - Copy a block of data into user space. * @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. * * Returns number of bytes that could not be copied. * On success, this will be zero. */#define copy_to_user(to,from,n)				\({							\	might_sleep();					\	__generic_copy_to_user((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. */#define __copy_from_user(to,from,n)			\	__generic_copy_from_user_nocheck((to),(from),(n))/** * copy_from_user: - Copy a block of data from user space. * @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. * * 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. */#define copy_from_user(to,from,n)			\({							\	might_sleep();					\__generic_copy_from_user((to),(from),(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);/** * __clear_user: - Zero a block of memory in user space, with less checking. * @to:   Destination address, in user space. * @n:    Number of bytes to zero. * * Zero a block of memory in user space.  Caller must check * the specified block with access_ok() before calling this function. * * Returns number of bytes that could not be cleared. * On success, this will be zero. */unsigned long __clear_user(void __user *mem, unsigned long len);/** * clear_user: - Zero a block of memory in user space. * @to:   Destination address, in user space. * @n:    Number of bytes to zero. * * Zero a block of memory in user space.  Caller must check * the specified block with access_ok() before calling this function. * * Returns number of bytes that could not be cleared. * On success, this will be zero. */unsigned long clear_user(void __user *mem, unsigned long len);/** * 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);#endif /* _ASM_M32R_UACCESS_H */

⌨️ 快捷键说明

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