/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1996, 1997, 1998, 1999, 2000, 03, 04 by Ralf Baechle * Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 2007 Maciej W. Rozycki * Copyright (C) 2014, Imagination Technologies Ltd.
*/ #ifndef _ASM_UACCESS_H #define _ASM_UACCESS_H
/* * put_user: - Write a simple value into user space. * @x: Value to copy to user space. * @ptr: Destination address, in user space. * * Context: User context only. This function may sleep if pagefaults are * enabled. * * This macro copies a single simple value from kernel space to user * space. It supports simple types like char and int, but not larger * data types like structures or arrays. * * @ptr must have pointer-to-simple-variable type, and @x must be assignable * to the result of dereferencing @ptr. * * Returns zero on success, or -EFAULT on error.
*/ #define put_user(x, ptr) \
({ \
__typeof__(*(ptr)) __user *__p = (ptr); \
\
might_fault(); \
access_ok(__p, sizeof(*__p)) ? __put_user((x), __p) : -EFAULT; \
})
/* * get_user: - Get a simple variable from user space. * @x: Variable to store result. * @ptr: Source address, in user space. * * Context: User context only. This function may sleep if pagefaults are * enabled. * * This macro copies a single simple variable from user space to kernel * space. It supports simple types like char and int, but not larger * data types like structures or arrays. * * @ptr must have pointer-to-simple-variable type, and the result of * dereferencing @ptr must be assignable to @x without a cast. * * Returns zero on success, or -EFAULT on error. * On error, the variable @x is set to zero.
*/ #define get_user(x, ptr) \
({ \ const __typeof__(*(ptr)) __user *__p = (ptr); \
\
might_fault(); \
access_ok(__p, sizeof(*__p)) ? __get_user((x), __p) : \
((x) = 0, -EFAULT); \
})
/* * __put_user: - Write a simple value into user space, with less checking. * @x: Value to copy to user space. * @ptr: Destination address, in user space. * * Context: User context only. This function may sleep if pagefaults are * enabled. * * This macro copies a single simple value from kernel space to user * space. It supports simple types like char and int, but not larger * data types like structures or arrays. * * @ptr must have pointer-to-simple-variable type, and @x must be assignable * to the result of dereferencing @ptr. * * Caller must check the pointer with access_ok() before calling this * function. * * Returns zero on success, or -EFAULT on error.
*/ #define __put_user(x, ptr) \
({ \
__typeof__(*(ptr)) __user *__pu_ptr = (ptr); \
__typeof__(*(ptr)) __pu_val = (x); \ int __pu_err = 0; \
\
__chk_user_ptr(__pu_ptr); \ switch (sizeof(*__pu_ptr)) { \ case 1: \
__put_data_asm(user_sb, __pu_ptr); \ break; \ case 2: \
__put_data_asm(user_sh, __pu_ptr); \ break; \ case 4: \
__put_data_asm(user_sw, __pu_ptr); \ break; \ case 8: \
__PUT_DW(user_sd, __pu_ptr); \ break; \ default: \
BUILD_BUG(); \
} \
\
__pu_err; \
})
/* * __get_user: - Get a simple variable from user space, with less checking. * @x: Variable to store result. * @ptr: Source address, in user space. * * Context: User context only. This function may sleep if pagefaults are * enabled. * * This macro copies a single simple variable from user space to kernel * space. It supports simple types like char and int, but not larger * data types like structures or arrays. * * @ptr must have pointer-to-simple-variable type, and the result of * dereferencing @ptr must be assignable to @x without a cast. * * Caller must check the pointer with access_ok() before calling this * function. * * Returns zero on success, or -EFAULT on error. * On error, the variable @x is set to zero.
*/ #define __get_user(x, ptr) \
({ \ const __typeof__(*(ptr)) __user *__gu_ptr = (ptr); \ int __gu_err = 0; \
\
__chk_user_ptr(__gu_ptr); \ switch (sizeof(*__gu_ptr)) { \ case 1: \
__get_data_asm((x), user_lb, __gu_ptr); \ break; \ case 2: \
__get_data_asm((x), user_lh, __gu_ptr); \ break; \ case 4: \
__get_data_asm((x), user_lw, __gu_ptr); \ break; \ case 8: \
__GET_DW((x), user_ld, __gu_ptr); \ break; \ default: \
BUILD_BUG(); \
} \
\
__gu_err; \
})
#define __get_kernel_nofault(dst, src, type, err_label) \ do { \ int __gu_err; \
\ switch (sizeof(type)) { \ case 1: \
__get_data_asm(*(type *)(dst), kernel_lb, \
(__force type *)(src)); \ break; \ case 2: \
__get_data_asm(*(type *)(dst), kernel_lh, \
(__force type *)(src)); \ break; \ case 4: \
__get_data_asm(*(type *)(dst), kernel_lw, \
(__force type *)(src)); \ break; \ case 8: \
__GET_DW(*(type *)(dst), kernel_ld, \
(__force type *)(src)); \ break; \ default: \
BUILD_BUG(); \ break; \
} \ if (unlikely(__gu_err)) \ goto err_label; \
} while (0)
/* * Yuck. We need two variants, one for 64bit operation and one * for 32 bit mode and old iron.
*/ #ifdef CONFIG_32BIT #define __PUT_DW(insn, ptr) __put_data_asm_ll32(insn, ptr) #endif #ifdef CONFIG_64BIT #define __PUT_DW(insn, ptr) __put_data_asm(insn, ptr) #endif
/* * __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.
*/ staticinline __kernel_size_t
__clear_user(void __user *addr, __kernel_size_t size)
{
__kernel_size_t res;
externlong __strncpy_from_user_asm(char *__to, constchar __user *__from, long __len);
/* * strncpy_from_user: - Copy a NUL terminated string from userspace. * @dst: Destination address, in kernel space. This buffer must be at * least @count bytes long. * @src: Source address, in user space. * @count: Maximum number of bytes to copy, including the trailing NUL. * * Copies a NUL-terminated string from userspace to kernel space. * * On success, returns the length of the string (not including the trailing * NUL). * * If access to userspace fails, returns -EFAULT (some data may have been * copied). * * If @count is smaller than the length of the string, copies @count bytes * and returns @count.
*/ staticinlinelong
strncpy_from_user(char *__to, constchar __user *__from, long __len)
{ long res;
externlong __strnlen_user_asm(constchar __user *s, long n);
/* * strnlen_user: - Get the size of a string in user space. * @str: The string to measure. * * Context: User context only. This function may sleep if pagefaults are * enabled. * * 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 the string is too long, returns a value greater than @n.
*/ staticinlinelong strnlen_user(constchar __user *s, long n)
{ long res;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.