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 + -
显示快捷键?