11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef _ASM_M32R_UACCESS_H
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define _ASM_M32R_UACCESS_H
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  linux/include/asm-m32r/uaccess.h
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  M32R version.
804dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata *    Copyright (C) 2004, 2006  Hirokazu Takata <takata at linux-m32r.org>
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * User space memory access functions
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h>
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/thread_info.h>
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/page.h>
17ec0ced156f930aba24e7527905de294ad929ef65Adrian Bunk#include <asm/setup.h>
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define VERIFY_READ 0
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define VERIFY_WRITE 1
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The fs value determines whether argument validity checking should be
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * performed or not.  If get_fs() == USER_DS, checking is performed, with
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * get_fs() == KERNEL_DS, checking is bypassed.
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * For historical reasons, these macros are grossly misnamed.
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_MMU
3304dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define KERNEL_DS	MAKE_MM_SEG(0xFFFFFFFF)
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define USER_DS		MAKE_MM_SEG(PAGE_OFFSET)
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define get_ds()	(KERNEL_DS)
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define get_fs()	(current_thread_info()->addr_limit)
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define set_fs(x)	(current_thread_info()->addr_limit = (x))
3904dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata
4004dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata#else /* not CONFIG_MMU */
4104dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata
4204dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata#define KERNEL_DS	MAKE_MM_SEG(0xFFFFFFFF)
4304dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata#define USER_DS		MAKE_MM_SEG(0xFFFFFFFF)
4404dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata#define get_ds()	(KERNEL_DS)
4504dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline mm_segment_t get_fs(void)
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4804dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	return USER_DS;
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void set_fs(mm_segment_t s)
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5404dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata
5504dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata#endif /* not CONFIG_MMU */
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define segment_eq(a,b)	((a).seg == (b).seg)
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __addr_ok(addr) \
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	((unsigned long)(addr) < (current_thread_info()->addr_limit.seg))
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Test whether a block of memory is a valid user space address.
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns 0 if the range is valid, nonzero otherwise.
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This is equivalent to the following test:
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (u33)addr + (u33)size >= (u33)current->addr_limit.seg
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This needs 33-bit arithmetic. We have a carry...
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __range_ok(addr,size) ({					\
7216cf5b39b81b95d1e3d81df3ba8c82cadf54f551Tilman Schmidt	unsigned long flag, roksum; 					\
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__chk_user_ptr(addr);						\
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	asm ( 								\
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	cmpu	%1, %1    ; clear cbit\n"		\
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	addx	%1, %3    ; set cbit if overflow\n"	\
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	subx	%0, %0\n"				\
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	cmpu	%4, %1\n"				\
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	subx	%0, %5\n"				\
8016cf5b39b81b95d1e3d81df3ba8c82cadf54f551Tilman Schmidt		: "=&r" (flag), "=r" (roksum)				\
8104dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		: "1" (addr), "r" ((int)(size)), 			\
8204dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		  "r" (current_thread_info()->addr_limit.seg), "r" (0)	\
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		: "cbit" );						\
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	flag; })
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * access_ok: - Checks if a user space pointer is valid
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE.  Note that
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *        %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *        to write to a block, it is always safe to read from it.
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @addr: User space pointer to start of block to check
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @size: Size of block to check
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Context: User context only.  This function may sleep.
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Checks if a pointer to a block of memory in user space is valid.
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns true (nonzero) if the memory block may be valid, false (zero)
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * if it is definitely invalid.
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Note that, depending on architecture, this function probably just
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * checks that the pointer is in the user space range - after calling
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * this function, memory access functions may still return -EFAULT.
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_MMU
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define access_ok(type,addr,size) (likely(__range_ok(addr,size) == 0))
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int access_ok(int type, const void *addr, unsigned long size)
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
11004dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	unsigned long val = (unsigned long)addr;
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11204dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	return ((val >= memory_start) && ((val + size) < memory_end));
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_MMU */
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The exception table consists of pairs of addresses: the first is the
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * address of an instruction that is allowed to fault, and the second is
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the address at which the program should continue.  No registers are
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * modified, so it is entirely up to the continuation code to figure out
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * what to do.
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * All the routines below use bits of fixup code that are out of line
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * with the main instruction path.  This means when everything is well,
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * we don't even have to jump over them.  Further, they do not intrude
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * on our cache or tlb entries.
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct exception_table_entry
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long insn, fixup;
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern int fixup_exception(struct pt_regs *regs);
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * These are the main single-value transfer routines.  They automatically
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * use the right size if we just have the right pointer type.
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This gets kind of ugly. We want to return _two_ values in "get_user()"
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and yet we don't want to do any pointers, because that is too much
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of a performance impact. Thus we have a few rather ugly macros here,
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and hide all the uglyness from the user.
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The "__xxx" versions of the user access functions are versions that
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * do not verify the address space, that must have been done previously
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * with a separate "access_ok()" call (this is used when we do multiple
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * accesses to the same area of user memory).
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Careful: we have to cast the result to the type of the pointer for sign
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds   reasons */
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * get_user: - Get a simple variable from user space.
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @x:   Variable to store result.
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @ptr: Source address, in user space.
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Context: User context only.  This function may sleep.
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This macro copies a single simple variable from user space to kernel
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * space.  It supports simple types like char and int, but not larger
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * data types like structures or arrays.
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @ptr must have pointer-to-simple-variable type, and the result of
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * dereferencing @ptr must be assignable to @x without a cast.
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns zero on success, or -EFAULT on error.
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * On error, the variable @x is set to zero.
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define get_user(x,ptr)							\
17104dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	__get_user_check((x),(ptr),sizeof(*(ptr)))
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * put_user: - Write a simple value into user space.
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @x:   Value to copy to user space.
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @ptr: Destination address, in user space.
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Context: User context only.  This function may sleep.
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This macro copies a single simple value from kernel space to user
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * space.  It supports simple types like char and int, but not larger
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * data types like structures or arrays.
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @ptr must have pointer-to-simple-variable type, and @x must be assignable
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to the result of dereferencing @ptr.
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns zero on success, or -EFAULT on error.
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define put_user(x,ptr)							\
19004dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	__put_user_check((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * __get_user: - Get a simple variable from user space, with less checking.
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @x:   Variable to store result.
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @ptr: Source address, in user space.
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Context: User context only.  This function may sleep.
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This macro copies a single simple variable from user space to kernel
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * space.  It supports simple types like char and int, but not larger
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * data types like structures or arrays.
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @ptr must have pointer-to-simple-variable type, and the result of
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * dereferencing @ptr must be assignable to @x without a cast.
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Caller must check the pointer with access_ok() before calling this
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * function.
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns zero on success, or -EFAULT on error.
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * On error, the variable @x is set to zero.
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __get_user(x,ptr) \
21304dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	__get_user_nocheck((x),(ptr),sizeof(*(ptr)))
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
21504dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata#define __get_user_nocheck(x,ptr,size)					\
21604dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata({									\
21704dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	long __gu_err = 0;						\
21804dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	unsigned long __gu_val;						\
21901682576d5fd1c92b96d79560b17208a6567c331Michael S. Tsirkin	might_fault();							\
22004dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	__get_user_size(__gu_val,(ptr),(size),__gu_err);		\
22104dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	(x) = (__typeof__(*(ptr)))__gu_val;				\
22204dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	__gu_err;							\
22304dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata})
22404dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata
22504dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata#define __get_user_check(x,ptr,size)					\
22604dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata({									\
22704dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	long __gu_err = -EFAULT;					\
22804dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	unsigned long __gu_val = 0;					\
22904dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	const __typeof__(*(ptr)) __user *__gu_addr = (ptr);		\
23001682576d5fd1c92b96d79560b17208a6567c331Michael S. Tsirkin	might_fault();							\
23104dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	if (access_ok(VERIFY_READ,__gu_addr,size))			\
23204dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		__get_user_size(__gu_val,__gu_addr,(size),__gu_err);	\
23304dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	(x) = (__typeof__(*(ptr)))__gu_val;				\
23404dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	__gu_err;							\
23504dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata})
23604dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata
23704dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takataextern long __get_user_bad(void);
23804dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata
23904dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata#define __get_user_size(x,ptr,size,retval)				\
24004dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takatado {									\
24104dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	retval = 0;							\
24204dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	__chk_user_ptr(ptr);						\
24304dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	switch (size) {							\
24404dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	  case 1: __get_user_asm(x,ptr,retval,"ub"); break;		\
24504dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	  case 2: __get_user_asm(x,ptr,retval,"uh"); break;		\
24604dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	  case 4: __get_user_asm(x,ptr,retval,""); break;		\
24704dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	  default: (x) = __get_user_bad();				\
24804dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	}								\
24904dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata} while (0)
25004dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata
25104dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata#define __get_user_asm(x, addr, err, itype)				\
25204dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	__asm__ __volatile__(						\
25304dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		"	.fillinsn\n"					\
25404dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		"1:	ld"itype" %1,@%2\n"				\
25504dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		"	.fillinsn\n"					\
25604dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		"2:\n"							\
25704dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		".section .fixup,\"ax\"\n"				\
25804dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		"	.balign 4\n"					\
25904dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		"3:	ldi %0,%3\n"					\
26004dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		"	seth r14,#high(2b)\n"				\
26104dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		"	or3 r14,r14,#low(2b)\n"				\
26204dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		"	jmp r14\n"					\
26304dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		".previous\n"						\
26404dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		".section __ex_table,\"a\"\n"				\
26504dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		"	.balign 4\n"					\
26604dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		"	.long 1b,3b\n"					\
26704dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		".previous"						\
26804dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		: "=&r" (err), "=&r" (x)				\
26904dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		: "r" (addr), "i" (-EFAULT), "0" (err)			\
27004dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		: "r14", "memory")
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * __put_user: - Write a simple value into user space, with less checking.
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @x:   Value to copy to user space.
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @ptr: Destination address, in user space.
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Context: User context only.  This function may sleep.
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This macro copies a single simple value from kernel space to user
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * space.  It supports simple types like char and int, but not larger
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * data types like structures or arrays.
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @ptr must have pointer-to-simple-variable type, and @x must be assignable
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to the result of dereferencing @ptr.
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Caller must check the pointer with access_ok() before calling this
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * function.
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns zero on success, or -EFAULT on error.
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __put_user(x,ptr) \
29204dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	__put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
29304dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __put_user_nocheck(x,ptr,size)					\
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds({									\
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	long __pu_err;							\
29801682576d5fd1c92b96d79560b17208a6567c331Michael S. Tsirkin	might_fault();							\
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__put_user_size((x),(ptr),(size),__pu_err);			\
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__pu_err;							\
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds})
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __put_user_check(x,ptr,size)					\
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds({									\
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	long __pu_err = -EFAULT;					\
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__typeof__(*(ptr)) __user *__pu_addr = (ptr);			\
30801682576d5fd1c92b96d79560b17208a6567c331Michael S. Tsirkin	might_fault();							\
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (access_ok(VERIFY_WRITE,__pu_addr,size))			\
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		__put_user_size((x),__pu_addr,(size),__pu_err);		\
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__pu_err;							\
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds})
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if defined(__LITTLE_ENDIAN__)
31504dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata#define __put_user_u64(x, addr, err)					\
31604dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata        __asm__ __volatile__(						\
31704dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                "       .fillinsn\n"					\
31804dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                "1:     st %L1,@%2\n"					\
31904dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                "       .fillinsn\n"					\
32004dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                "2:     st %H1,@(4,%2)\n"				\
32104dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                "       .fillinsn\n"					\
32204dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                "3:\n"							\
32304dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                ".section .fixup,\"ax\"\n"				\
32404dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                "       .balign 4\n"					\
32504dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                "4:     ldi %0,%3\n"					\
32604dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                "       seth r14,#high(3b)\n"				\
32704dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                "       or3 r14,r14,#low(3b)\n"				\
32804dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                "       jmp r14\n"					\
32904dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                ".previous\n"						\
33004dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                ".section __ex_table,\"a\"\n"				\
33104dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                "       .balign 4\n"					\
33204dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                "       .long 1b,4b\n"					\
33304dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                "       .long 2b,4b\n"					\
33404dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                ".previous"						\
33504dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                : "=&r" (err)						\
33604dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata                : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err)		\
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds                : "r14", "memory")
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#elif defined(__BIG_ENDIAN__)
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __put_user_u64(x, addr, err)					\
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__asm__ __volatile__(						\
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"1:	st %H1,@%2\n"					\
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"2:	st %L1,@(4,%2)\n"				\
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"3:\n"							\
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		".section .fixup,\"ax\"\n"				\
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.balign 4\n"					\
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"4:	ldi %0,%3\n"					\
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	seth r14,#high(3b)\n"				\
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	or3 r14,r14,#low(3b)\n"				\
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	jmp r14\n"					\
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		".previous\n"						\
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		".section __ex_table,\"a\"\n"				\
3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.balign 4\n"					\
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.long 1b,4b\n"					\
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.long 2b,4b\n"					\
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		".previous"						\
36004dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		: "=&r" (err)						\
36104dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		: "r" (x), "r" (addr), "i" (-EFAULT), "0" (err)		\
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		: "r14", "memory")
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#error no endian defined
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
36704dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takataextern void __put_user_bad(void);
36804dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __put_user_size(x,ptr,size,retval)				\
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdo {									\
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	retval = 0;							\
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__chk_user_ptr(ptr);						\
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (size) {							\
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	  case 1: __put_user_asm(x,ptr,retval,"b"); break;		\
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	  case 2: __put_user_asm(x,ptr,retval,"h"); break;		\
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	  case 4: __put_user_asm(x,ptr,retval,""); break;		\
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	  case 8: __put_user_u64((__typeof__(*ptr))(x),ptr,retval); break;\
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	  default: __put_user_bad();					\
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}								\
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} while (0)
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct __large_struct { unsigned long buf[100]; };
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __m(x) (*(struct __large_struct *)(x))
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Tell gcc we read from memory instead of writing: this is because
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * we do not write to any memory gcc knows about, so there are no
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * aliasing issues.
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __put_user_asm(x, addr, err, itype)				\
3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__asm__ __volatile__(						\
3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"1:	st"itype" %1,@%2\n"				\
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"2:\n"							\
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		".section .fixup,\"ax\"\n"				\
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.balign 4\n"					\
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"3:	ldi %0,%3\n"					\
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	seth r14,#high(2b)\n"				\
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	or3 r14,r14,#low(2b)\n"				\
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	jmp r14\n"					\
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		".previous\n"						\
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		".section __ex_table,\"a\"\n"				\
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.balign 4\n"					\
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.long 1b,3b\n"					\
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		".previous"						\
40704dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		: "=&r" (err)						\
40804dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		: "r" (x), "r" (addr), "i" (-EFAULT), "0" (err)		\
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		: "r14", "memory")
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Here we special-case 1, 2 and 4-byte copy_*_user invocations.  On a fault
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * we return the initial request size (1, 2 or 4), as copy_*_user should do.
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If a store crosses a page boundary and gets a fault, the m32r will not write
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * anything, so this is accurate.
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copy To/From Userspace
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Generic arbitrary sized copy.  */
4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Return the number of bytes NOT copied.  */
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __copy_user(to,from,size)					\
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdo {									\
4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long __dst, __src, __c;				\
4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__asm__ __volatile__ (						\
4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	mv	r14, %0\n"				\
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	or	r14, %1\n"				\
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	beq	%0, %1, 9f\n"				\
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	beqz	%2, 9f\n"				\
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	and3	r14, r14, #3\n"				\
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	bnez	r14, 2f\n"				\
4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	and3	%2, %2, #3\n"				\
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	beqz	%3, 2f\n"				\
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	addi	%0, #-4		; word_copy \n"		\
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"0:	ld	r14, @%1+\n"				\
4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	addi	%3, #-1\n"				\
4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"1:	st	r14, @+%0\n"				\
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	bnez	%3, 0b\n"				\
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	beqz	%2, 9f\n"				\
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	addi	%0, #4\n"				\
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"2:	ldb	r14, @%1	; byte_copy \n"		\
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"3:	stb	r14, @%0\n"				\
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	addi	%1, #1\n"				\
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	addi	%2, #-1\n"				\
4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	addi	%0, #1\n"				\
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	bnez	%2, 2b\n"				\
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"9:\n"							\
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		".section .fixup,\"ax\"\n"				\
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.balign 4\n"					\
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"5:	addi	%3, #1\n"				\
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	addi	%1, #-4\n"				\
4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"6:	slli	%3, #2\n"				\
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	add	%2, %3\n"				\
4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	addi	%0, #4\n"				\
4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"7:	seth	r14, #high(9b)\n"			\
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	or3	r14, r14, #low(9b)\n"			\
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	jmp	r14\n"					\
4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		".previous\n"						\
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		".section __ex_table,\"a\"\n"				\
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.balign 4\n"					\
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.long 0b,6b\n"					\
4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.long 1b,5b\n"					\
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.long 2b,9b\n"					\
4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.long 3b,9b\n"					\
4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		".previous\n"						\
47504dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		: "=&r" (__dst), "=&r" (__src), "=&r" (size),		\
47604dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		  "=&r" (__c)						\
47704dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		: "0" (to), "1" (from), "2" (size), "3" (size / 4)	\
4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		: "r14", "memory");					\
4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} while (0)
4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __copy_user_zeroing(to,from,size)				\
4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdo {									\
4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long __dst, __src, __c;				\
4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__asm__ __volatile__ (						\
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	mv	r14, %0\n"				\
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	or	r14, %1\n"				\
4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	beq	%0, %1, 9f\n"				\
4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	beqz	%2, 9f\n"				\
4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	and3	r14, r14, #3\n"				\
4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	bnez	r14, 2f\n"				\
4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	and3	%2, %2, #3\n"				\
4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	beqz	%3, 2f\n"				\
4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	addi	%0, #-4		; word_copy \n"		\
4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"0:	ld	r14, @%1+\n"				\
4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	addi	%3, #-1\n"				\
4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"1:	st	r14, @+%0\n"				\
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	bnez	%3, 0b\n"				\
5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	beqz	%2, 9f\n"				\
5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	addi	%0, #4\n"				\
5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"2:	ldb	r14, @%1	; byte_copy \n"		\
5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"3:	stb	r14, @%0\n"				\
5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	addi	%1, #1\n"				\
5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	addi	%2, #-1\n"				\
5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	addi	%0, #1\n"				\
5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	bnez	%2, 2b\n"				\
5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"9:\n"							\
5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		".section .fixup,\"ax\"\n"				\
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.balign 4\n"					\
5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"5:	addi	%3, #1\n"				\
5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	addi	%1, #-4\n"				\
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"6:	slli	%3, #2\n"				\
5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	add	%2, %3\n"				\
5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	addi	%0, #4\n"				\
5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"7:	ldi	r14, #0		; store zero \n"	\
5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.fillinsn\n"					\
5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"8:	addi	%2, #-1\n"				\
5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	stb	r14, @%0	; ACE? \n"		\
5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	addi	%0, #1\n"				\
5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	bnez	%2, 8b\n"				\
5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	seth	r14, #high(9b)\n"			\
5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	or3	r14, r14, #low(9b)\n"			\
5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	jmp	r14\n"					\
5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		".previous\n"						\
5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		".section __ex_table,\"a\"\n"				\
5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.balign 4\n"					\
5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.long 0b,6b\n"					\
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.long 1b,5b\n"					\
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.long 2b,7b\n"					\
5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		"	.long 3b,7b\n"					\
5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		".previous\n"						\
53804dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		: "=&r" (__dst), "=&r" (__src), "=&r" (size),		\
53904dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		  "=&r" (__c)						\
54004dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata		: "0" (to), "1" (from), "2" (size), "3" (size / 4)	\
5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		: "r14", "memory");					\
5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} while (0)
5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* We let the __ versions of copy_from/to_user inline, because they're often
5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * used in fast paths and have only a small space overhead.
5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline unsigned long __generic_copy_from_user_nocheck(void *to,
5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	const void __user *from, unsigned long n)
5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__copy_user_zeroing(to,from,n);
5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return n;
5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline unsigned long __generic_copy_to_user_nocheck(void __user *to,
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	const void *from, unsigned long n)
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__copy_user(to,from,n);
5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return n;
5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
562a880948b2b88c05af9a471ca5c52883e64d3f7b8Al Virounsigned long __generic_copy_to_user(void __user *, const void *, unsigned long);
563a880948b2b88c05af9a471ca5c52883e64d3f7b8Al Virounsigned long __generic_copy_from_user(void *, const void __user *, unsigned long);
5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * __copy_to_user: - Copy a block of data into user space, with less checking.
5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @to:   Destination address, in user space.
5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @from: Source address, in kernel space.
5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @n:    Number of bytes to copy.
5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Context: User context only.  This function may sleep.
5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copy data from kernel space to user space.  Caller must check
5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the specified block with access_ok() before calling this function.
5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns number of bytes that could not be copied.
5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * On success, this will be zero.
5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __copy_to_user(to,from,n)			\
5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__generic_copy_to_user_nocheck((to),(from),(n))
5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __copy_to_user_inatomic __copy_to_user
5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __copy_from_user_inatomic __copy_from_user
5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * copy_to_user: - Copy a block of data into user space.
5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @to:   Destination address, in user space.
5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @from: Source address, in kernel space.
5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @n:    Number of bytes to copy.
5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Context: User context only.  This function may sleep.
5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copy data from kernel space to user space.
5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns number of bytes that could not be copied.
5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * On success, this will be zero.
5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define copy_to_user(to,from,n)				\
5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds({							\
60001682576d5fd1c92b96d79560b17208a6567c331Michael S. Tsirkin	might_fault();					\
6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__generic_copy_to_user((to),(from),(n));	\
6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds})
6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * __copy_from_user: - Copy a block of data from user space, with less checking. * @to:   Destination address, in kernel space.
6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @from: Source address, in user space.
6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @n:    Number of bytes to copy.
6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Context: User context only.  This function may sleep.
6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copy data from user space to kernel space.  Caller must check
6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the specified block with access_ok() before calling this function.
6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns number of bytes that could not be copied.
6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * On success, this will be zero.
6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If some data could not be copied, this function will pad the copied
6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * data to the requested size using zero bytes.
6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __copy_from_user(to,from,n)			\
6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	__generic_copy_from_user_nocheck((to),(from),(n))
6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * copy_from_user: - Copy a block of data from user space.
6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @to:   Destination address, in kernel space.
6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @from: Source address, in user space.
6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @n:    Number of bytes to copy.
6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Context: User context only.  This function may sleep.
6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copy data from user space to kernel space.
6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns number of bytes that could not be copied.
6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * On success, this will be zero.
6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If some data could not be copied, this function will pad the copied
6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * data to the requested size using zero bytes.
6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define copy_from_user(to,from,n)			\
6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds({							\
64101682576d5fd1c92b96d79560b17208a6567c331Michael S. Tsirkin	might_fault();					\
64204dfd0de4ec04aaf7d9d42439c972c642a15a75cHirokazu Takata	__generic_copy_from_user((to),(from),(n));	\
6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds})
6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldslong __must_check strncpy_from_user(char *dst, const char __user *src,
6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				long count);
6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldslong __must_check __strncpy_from_user(char *dst,
6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				const char __user *src, long count);
6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * __clear_user: - Zero a block of memory in user space, with less checking.
6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @to:   Destination address, in user space.
6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @n:    Number of bytes to zero.
6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Zero a block of memory in user space.  Caller must check
6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the specified block with access_ok() before calling this function.
6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns number of bytes that could not be cleared.
6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * On success, this will be zero.
6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsunsigned long __clear_user(void __user *mem, unsigned long len);
6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * clear_user: - Zero a block of memory in user space.
6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @to:   Destination address, in user space.
6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @n:    Number of bytes to zero.
6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Zero a block of memory in user space.  Caller must check
6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the specified block with access_ok() before calling this function.
6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns number of bytes that could not be cleared.
6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * On success, this will be zero.
6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsunsigned long clear_user(void __user *mem, unsigned long len);
6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/**
6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * strlen_user: - Get the size of a string in user space.
6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @str: The string to measure.
6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Context: User context only.  This function may sleep.
6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Get the size of a NUL-terminated string in user space.
6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns the size of the string INCLUDING the terminating NUL.
6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * On exception, returns 0.
6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * If there is a limit on the length of a valid string, you may wish to
6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * consider using strnlen_user() instead.
6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldslong strnlen_user(const char __user *str, long n);
6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* _ASM_M32R_UACCESS_H */
694