1b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/* MN10300 userspace access functions
2b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells *
3b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * Written by David Howells (dhowells@redhat.com)
5b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells *
6b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * This program is free software; you can redistribute it and/or
7b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * modify it under the terms of the GNU General Public Licence
8b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * as published by the Free Software Foundation; either version
9b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * 2 of the Licence, or (at your option) any later version.
10b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells */
11b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#ifndef _ASM_UACCESS_H
12b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define _ASM_UACCESS_H
13b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
14b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/*
15b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * User space memory access functions
16b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells */
177c7fcf762e405eb040ee10d22d656a791f616122David Howells#include <linux/thread_info.h>
1835052cffe0081904f3362c05818db900dd9dc7deDavid Howells#include <linux/kernel.h>
19b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#include <asm/page.h>
20b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#include <asm/errno.h>
21b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
22b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define VERIFY_READ 0
23b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define VERIFY_WRITE 1
24b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
25b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/*
26b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * The fs value determines whether argument validity checking should be
27b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * performed or not.  If get_fs() == USER_DS, checking is performed, with
28b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * get_fs() == KERNEL_DS, checking is bypassed.
29b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells *
30b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * For historical reasons, these macros are grossly misnamed.
31b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells */
32b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
33b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
34b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define KERNEL_XDS	MAKE_MM_SEG(0xBFFFFFFF)
35b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define KERNEL_DS	MAKE_MM_SEG(0x9FFFFFFF)
36b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define USER_DS		MAKE_MM_SEG(TASK_SIZE)
37b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
38b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define get_ds()	(KERNEL_DS)
39b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define get_fs()	(current_thread_info()->addr_limit)
40b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define set_fs(x)	(current_thread_info()->addr_limit = (x))
41b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __kernel_ds_p() (current_thread_info()->addr_limit.seg == 0x9FFFFFFF)
42b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
43b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define segment_eq(a, b) ((a).seg == (b).seg)
44b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
45b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __addr_ok(addr) \
46b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	((unsigned long)(addr) < (current_thread_info()->addr_limit.seg))
47b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
48b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/*
49b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * check that a range of addresses falls within the current address limit
50b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells */
51b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstatic inline int ___range_ok(unsigned long addr, unsigned int size)
52b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells{
53b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	int flag = 1, tmp;
54b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
55b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	asm("	add	%3,%1	\n"	/* set C-flag if addr + size > 4Gb */
56b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	    "	bcs	0f	\n"
57b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	    "	cmp	%4,%1	\n"	/* jump if addr+size>limit (error) */
58b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	    "	bhi	0f	\n"
59b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	    "	clr	%0	\n"	/* mark okay */
60b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	    "0:			\n"
61b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	    : "=r"(flag), "=&r"(tmp)
62b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	    : "1"(addr), "ir"(size),
63b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	      "r"(current_thread_info()->addr_limit.seg), "0"(flag)
64b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	    : "cc"
65b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	    );
66b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
67b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	return flag;
68b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells}
69b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
70b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __range_ok(addr, size) ___range_ok((unsigned long)(addr), (u32)(size))
71b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
72b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0)
73b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __access_ok(addr, size)     (__range_ok((addr), (size)) == 0)
74b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
75b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstatic inline int verify_area(int type, const void *addr, unsigned long size)
76b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells{
77b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	return access_ok(type, addr, size) ? 0 : -EFAULT;
78b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells}
79b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
80b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
81b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/*
82b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * The exception table consists of pairs of addresses: the first is the
83b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * address of an instruction that is allowed to fault, and the second is
84b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * the address at which the program should continue.  No registers are
85b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * modified, so it is entirely up to the continuation code to figure out
86b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * what to do.
87b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells *
88b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * All the routines below use bits of fixup code that are out of line
89b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * with the main instruction path.  This means when everything is well,
90b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * we don't even have to jump over them.  Further, they do not intrude
91b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * on our cache or tlb entries.
92b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells */
93b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
94b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstruct exception_table_entry
95b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells{
96b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	unsigned long insn, fixup;
97b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells};
98b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
99b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/* Returns 0 if exception not found and fixup otherwise.  */
100b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern int fixup_exception(struct pt_regs *regs);
101b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
102b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define put_user(x, ptr) __put_user_check((x), (ptr), sizeof(*(ptr)))
103b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define get_user(x, ptr) __get_user_check((x), (ptr), sizeof(*(ptr)))
104b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
105b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/*
106b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * The "__xxx" versions do not do address space checking, useful when
107b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * doing multiple accesses to the same area (the user has to do the
108b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * checks by hand with "access_ok()")
109b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells */
110b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __put_user(x, ptr) __put_user_nocheck((x), (ptr), sizeof(*(ptr)))
111b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __get_user(x, ptr) __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
112b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
113b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/*
114b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * The "xxx_ret" versions return constant specified in third argument, if
115b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * something bad happens. These macros can be optimized for the
116b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * case of just returning from the function xxx_ret is used.
117b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells */
118b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
119b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define put_user_ret(x, ptr, ret) \
120b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	({ if (put_user((x), (ptr)))	return (ret); })
121b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define get_user_ret(x, ptr, ret) \
122b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	({ if (get_user((x), (ptr)))	return (ret); })
123b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __put_user_ret(x, ptr, ret) \
124b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	({ if (__put_user((x), (ptr)))	return (ret); })
125b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __get_user_ret(x, ptr, ret) \
126b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	({ if (__get_user((x), (ptr)))	return (ret); })
127b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
128b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstruct __large_struct { unsigned long buf[100]; };
129b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __m(x) (*(struct __large_struct *)(x))
130b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
131d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter#define __get_user_nocheck(x, ptr, size)				\
132d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter({									\
133d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter	unsigned long __gu_addr;					\
134d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter	int __gu_err;							\
135d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter	__gu_addr = (unsigned long) (ptr);				\
136d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter	switch (size) {							\
137d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter	case 1: {							\
138d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter		unsigned char __gu_val;					\
139d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter		__get_user_asm("bu");					\
140d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter		(x) = *(__force __typeof__(*(ptr))*) &__gu_val;		\
141d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter		break;							\
142d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter	}								\
143d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter	case 2: {							\
144d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter		unsigned short __gu_val;				\
145d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter		__get_user_asm("hu");					\
146d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter		(x) = *(__force __typeof__(*(ptr))*) &__gu_val;		\
147d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter		break;							\
148d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter	}								\
149d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter	case 4: {							\
150d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter		unsigned int __gu_val;					\
151d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter		__get_user_asm("");					\
152d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter		(x) = *(__force __typeof__(*(ptr))*) &__gu_val;		\
153d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter		break;							\
154d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter	}								\
155d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter	default:							\
156d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter		__get_user_unknown();					\
157d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter		break;							\
158d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter	}								\
159d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter	__gu_err;							\
160b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells})
161b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
162d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter#define __get_user_check(x, ptr, size)					\
163d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter({									\
164c6dc9f0a4eeb7c014904475372c66e6d0ac5a572Akira Takeuchi	const __typeof__(*(ptr))* __guc_ptr = (ptr);			\
165d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter	int _e;								\
1666fc34436be2494c6fea63dc0759be9b360d9480aTkhai Kirill	if (likely(__access_ok((unsigned long) __guc_ptr, (size))))	\
1676fc34436be2494c6fea63dc0759be9b360d9480aTkhai Kirill		_e = __get_user_nocheck((x), __guc_ptr, (size));	\
168d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter	else {								\
169d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter		_e = -EFAULT;						\
170d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter		(x) = (__typeof__(x))0;					\
171d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter	}								\
172d22a001bf6a502e978a8617e3f297b4d762cfbb5Mark Salter	_e;								\
173b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells})
174b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
175b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __get_user_asm(INSN)					\
176b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells({								\
177b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	asm volatile(					\
178b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"1:\n"						\
179b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	mov"INSN"	%2,%1\n"		\
180b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	mov		0,%0\n"			\
181b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"2:\n"						\
182b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	.section	.fixup,\"ax\"\n"	\
183b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"3:\n\t"					\
184b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	mov		%3,%0\n"		\
185b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	jmp		2b\n"			\
186b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	.previous\n"				\
187b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	.section	__ex_table,\"a\"\n"	\
188b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	.balign		4\n"			\
189b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	.long		1b, 3b\n"		\
190b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	.previous"				\
191b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		: "=&r" (__gu_err), "=&r" (__gu_val)		\
192b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		: "m" (__m(__gu_addr)), "i" (-EFAULT));		\
193b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells})
194b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
195b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern int __get_user_unknown(void);
196b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
197b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __put_user_nocheck(x, ptr, size)			\
198b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells({								\
199b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	union {							\
200b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		__typeof__(*(ptr)) val;				\
201b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		u32 bits[2];					\
202b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	} __pu_val;						\
203b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	unsigned long __pu_addr;				\
204b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	int __pu_err;						\
205b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	__pu_val.val = (x);					\
206b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	__pu_addr = (unsigned long) (ptr);			\
207b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	switch (size) {						\
208b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	case 1:  __put_user_asm("bu"); break;			\
209b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	case 2:  __put_user_asm("hu"); break;			\
210b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	case 4:  __put_user_asm(""  ); break;			\
211b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	case 8:  __put_user_asm8();    break;			\
212b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	default: __pu_err = __put_user_unknown(); break;	\
213b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	}							\
214b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	__pu_err;						\
215b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells})
216b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
217b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __put_user_check(x, ptr, size)					\
218b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells({									\
219b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	union {								\
220b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		__typeof__(*(ptr)) val;					\
221b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		u32 bits[2];						\
222b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	} __pu_val;							\
223b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	unsigned long __pu_addr;					\
224b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	int __pu_err;							\
225b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	__pu_val.val = (x);						\
226b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	__pu_addr = (unsigned long) (ptr);				\
227b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	if (likely(__access_ok(__pu_addr, size))) {			\
228b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		switch (size) {						\
229b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		case 1:  __put_user_asm("bu"); break;			\
230b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		case 2:  __put_user_asm("hu"); break;			\
231b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		case 4:  __put_user_asm(""  ); break;			\
232b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		case 8:  __put_user_asm8();    break;			\
233b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		default: __pu_err = __put_user_unknown(); break;	\
234b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		}							\
235b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	}								\
236b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	else {								\
237b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		__pu_err = -EFAULT;					\
238b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	}								\
239b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	__pu_err;							\
240b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells})
241b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
242b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __put_user_asm(INSN)					\
243b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells({								\
244b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	asm volatile(						\
245b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"1:\n"						\
246b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	mov"INSN"	%1,%2\n"		\
247b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	mov		0,%0\n"			\
248b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"2:\n"						\
249b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	.section	.fixup,\"ax\"\n"	\
250b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"3:\n"						\
251b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	mov		%3,%0\n"		\
252b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	jmp		2b\n"			\
253b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	.previous\n"				\
254b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	.section	__ex_table,\"a\"\n"	\
255b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	.balign		4\n"			\
256b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	.long		1b, 3b\n"		\
257b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	.previous"				\
258b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		: "=&r" (__pu_err)				\
259b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		: "r" (__pu_val.val), "m" (__m(__pu_addr)),	\
260b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		  "i" (-EFAULT)					\
261b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		);						\
262b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells})
263b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
264b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __put_user_asm8()						\
265b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells({									\
266b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	asm volatile(							\
267b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"1:	mov		%1,%3		\n"		\
268b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"2:	mov		%2,%4		\n"		\
269b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	mov		0,%0		\n"		\
270b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"3:					\n"		\
271b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	.section	.fixup,\"ax\"	\n"		\
272b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"4:					\n"		\
273b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	mov		%5,%0		\n"		\
27454b71fba68efbf3ab89721a384df2ce757750979Akira Takeuchi		"	jmp		3b		\n"		\
275b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	.previous			\n"		\
276b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	.section	__ex_table,\"a\"\n"		\
277b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	.balign		4		\n"		\
278b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	.long		1b, 4b		\n"		\
279b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	.long		2b, 4b		\n"		\
280b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"	.previous			\n"		\
281b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		: "=&r" (__pu_err)					\
282b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		: "r" (__pu_val.bits[0]), "r" (__pu_val.bits[1]),	\
283b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		  "m" (__m(__pu_addr)), "m" (__m(__pu_addr+4)),		\
284b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		  "i" (-EFAULT)						\
285b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		);							\
286b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells})
287b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
288b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern int __put_user_unknown(void);
289b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
290b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
291b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/*
292b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * Copy To/From Userspace
293b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells */
294b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/* Generic arbitrary sized copy.  */
295b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __copy_user(to, from, size)					\
296b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsdo {									\
297b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	if (size) {							\
298b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		void *__to = to;					\
299b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		const void *__from = from;				\
300b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		int w;							\
301b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		asm volatile(						\
302b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"0:     movbu	(%0),%3;\n"			\
303b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"1:     movbu	%3,(%1);\n"			\
304b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"	inc	%0;\n"				\
305b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"	inc	%1;\n"				\
306b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"       add	-1,%2;\n"			\
307b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"       bne	0b;\n"				\
308b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"2:\n"						\
309b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"	.section .fixup,\"ax\"\n"		\
310b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"3:	jmp	2b\n"				\
311b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"	.previous\n"				\
312b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"	.section __ex_table,\"a\"\n"		\
313b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"       .balign	4\n"				\
314b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"       .long	0b,3b\n"			\
315b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"       .long	1b,3b\n"			\
316b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"	.previous\n"				\
317b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			: "=a"(__from), "=a"(__to), "=r"(size), "=&r"(w)\
318b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			: "0"(__from), "1"(__to), "2"(size)		\
319d6bb7a1ad326f56f0793353c59348554f84b513cMark Salter			: "cc", "memory");				\
320b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	}								\
321b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells} while (0)
322b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
323b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __copy_user_zeroing(to, from, size)				\
324b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsdo {									\
325b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	if (size) {							\
326b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		void *__to = to;					\
327b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		const void *__from = from;				\
328b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		int w;							\
329b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		asm volatile(						\
330b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"0:     movbu	(%0),%3;\n"			\
331b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"1:     movbu	%3,(%1);\n"			\
332b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"	inc	%0;\n"				\
333b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"	inc	%1;\n"				\
334b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"       add	-1,%2;\n"			\
335b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"       bne	0b;\n"				\
336b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"2:\n"						\
337b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"	.section .fixup,\"ax\"\n"		\
338b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"3:\n"						\
339b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"	mov	%2,%0\n"			\
340b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"	clr	%3\n"				\
341b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"4:     movbu	%3,(%1);\n"			\
342b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"	inc	%1;\n"				\
343b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"       add	-1,%2;\n"			\
344b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"       bne	4b;\n"				\
345b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"	mov	%0,%2\n"			\
346b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"	jmp	2b\n"				\
347b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"	.previous\n"				\
348b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"	.section __ex_table,\"a\"\n"		\
349b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"       .balign	4\n"				\
350b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"       .long	0b,3b\n"			\
351b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"       .long	1b,3b\n"			\
352b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			"	.previous\n"				\
353b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			: "=a"(__from), "=a"(__to), "=r"(size), "=&r"(w)\
354b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells			: "0"(__from), "1"(__to), "2"(size)		\
355d6bb7a1ad326f56f0793353c59348554f84b513cMark Salter			: "cc", "memory");				\
356b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	}								\
357b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells} while (0)
358b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
359b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/* We let the __ versions of copy_from/to_user inline, because they're often
360b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells * used in fast paths and have only a small space overhead.
361b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells */
362b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstatic inline
363b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsunsigned long __generic_copy_from_user_nocheck(void *to, const void *from,
364b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells					       unsigned long n)
365b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells{
366b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	__copy_user_zeroing(to, from, n);
367b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	return n;
368b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells}
369b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
370b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstatic inline
371b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsunsigned long __generic_copy_to_user_nocheck(void *to, const void *from,
372b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells					     unsigned long n)
373b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells{
374b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	__copy_user(to, from, n);
375b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	return n;
376b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells}
377b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
378b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
379b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#if 0
380368dd5acd154b09c043cc4392a74da01599b37d5Akira Takeuchi#error "don't use - these macros don't increment to & from pointers"
381b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/* Optimize just a little bit when we know the size of the move. */
382b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __constant_copy_user(to, from, size)	\
383b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsdo {						\
384b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	asm volatile(				\
385b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"       mov %0,a0;\n"		\
386b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"0:     movbu (%1),d3;\n"	\
387b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"1:     movbu d3,(%2);\n"	\
388b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"       add -1,a0;\n"		\
389b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"       bne 0b;\n"		\
390b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"2:;"				\
391b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		".section .fixup,\"ax\"\n"	\
392b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"3:	jmp 2b\n"		\
393b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		".previous\n"			\
394b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		".section __ex_table,\"a\"\n"	\
395b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"       .balign 4\n"		\
396b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"       .long 0b,3b\n"		\
397b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"       .long 1b,3b\n"		\
398b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		".previous"			\
399b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		:				\
400b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		: "d"(size), "d"(to), "d"(from)	\
401b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		: "d3", "a0");			\
402b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells} while (0)
403b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
404b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells/* Optimize just a little bit when we know the size of the move. */
405b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __constant_copy_user_zeroing(to, from, size)	\
406b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsdo {							\
407b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	asm volatile(					\
408b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"       mov %0,a0;\n"			\
409b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"0:     movbu (%1),d3;\n"		\
410b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"1:     movbu d3,(%2);\n"		\
411b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"       add -1,a0;\n"			\
412b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"       bne 0b;\n"			\
413b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"2:;"					\
414b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		".section .fixup,\"ax\"\n"		\
415b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"3:	jmp 2b\n"			\
416b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		".previous\n"				\
417b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		".section __ex_table,\"a\"\n"		\
418b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"       .balign 4\n"			\
419b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"       .long 0b,3b\n"			\
420b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		"       .long 1b,3b\n"			\
421b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		".previous"				\
422b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		:					\
423b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		: "d"(size), "d"(to), "d"(from)		\
424b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		: "d3", "a0");				\
425b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells} while (0)
426b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
427b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstatic inline
428b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsunsigned long __constant_copy_to_user(void *to, const void *from,
429b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells				      unsigned long n)
430b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells{
431b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	if (access_ok(VERIFY_WRITE, to, n))
432b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		__constant_copy_user(to, from, n);
433b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	return n;
434b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells}
435b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
436b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstatic inline
437b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsunsigned long __constant_copy_from_user(void *to, const void *from,
438b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells					unsigned long n)
439b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells{
440b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	if (access_ok(VERIFY_READ, from, n))
441b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells		__constant_copy_user_zeroing(to, from, n);
442b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	return n;
443b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells}
444b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
445b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstatic inline
446b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsunsigned long __constant_copy_to_user_nocheck(void *to, const void *from,
447b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells					      unsigned long n)
448b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells{
449b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	__constant_copy_user(to, from, n);
450b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	return n;
451b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells}
452b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
453b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsstatic inline
454b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsunsigned long __constant_copy_from_user_nocheck(void *to, const void *from,
455b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells						unsigned long n)
456b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells{
457b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	__constant_copy_user_zeroing(to, from, n);
458b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	return n;
459b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells}
460b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#endif
461b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
462b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern unsigned long __generic_copy_to_user(void __user *, const void *,
463b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells					    unsigned long);
464b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern unsigned long __generic_copy_from_user(void *, const void __user *,
465b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells					      unsigned long);
466b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
467b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __copy_to_user_inatomic(to, from, n) \
468b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	__generic_copy_to_user_nocheck((to), (from), (n))
469b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __copy_from_user_inatomic(to, from, n) \
470b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	__generic_copy_from_user_nocheck((to), (from), (n))
471b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
472b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __copy_to_user(to, from, n)			\
473b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells({							\
4743837a3cfe4a27836e0e9f207eb2d4f00b5a8fcbaMichael S. Tsirkin	might_fault();					\
475b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	__copy_to_user_inatomic((to), (from), (n));	\
476b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells})
477b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
478b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define __copy_from_user(to, from, n)			\
479b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells({							\
4803837a3cfe4a27836e0e9f207eb2d4f00b5a8fcbaMichael S. Tsirkin	might_fault();					\
481b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells	__copy_from_user_inatomic((to), (from), (n));	\
482b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells})
483b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
484b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
485b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define copy_to_user(to, from, n)   __generic_copy_to_user((to), (from), (n))
486b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define copy_from_user(to, from, n) __generic_copy_from_user((to), (from), (n))
487b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
488b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern long strncpy_from_user(char *dst, const char __user *src, long count);
489b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern long __strncpy_from_user(char *dst, const char __user *src, long count);
490b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern long strnlen_user(const char __user *str, long n);
491b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
492b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern unsigned long clear_user(void __user *mem, unsigned long len);
493b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howellsextern unsigned long __clear_user(void __user *mem, unsigned long len);
494b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells
495b920de1b77b72ca9432ac3f97edb26541e65e5ddDavid Howells#endif /* _ASM_UACCESS_H */
496