1c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
2c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *  linux/include/asm-arm/uaccess.h
3c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
4c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * This program is free software; you can redistribute it and/or modify
5c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * it under the terms of the GNU General Public License version 2 as
6c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * published by the Free Software Foundation.
7c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
8c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef _ASMARM_UACCESS_H
9c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define _ASMARM_UACCESS_H
10c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
11c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
12c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * User space memory access functions
13c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
14c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <linux/sched.h>
15c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/errno.h>
16c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/memory.h>
17c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/domain.h>
18c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#include <asm/system.h>
19c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
20c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define VERIFY_READ 0
21c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define VERIFY_WRITE 1
22c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
23c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
24c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * The exception table consists of pairs of addresses: the first is the
25c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * address of an instruction that is allowed to fault, and the second is
26c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * the address at which the program should continue.  No registers are
27c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * modified, so it is entirely up to the continuation code to figure out
28c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * what to do.
29c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
30c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * All the routines below use bits of fixup code that are out of line
31c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * with the main instruction path.  This means when everything is well,
32c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * we don't even have to jump over them.  Further, they do not intrude
33c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * on our cache or tlb entries.
34c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
35c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
36c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustruct exception_table_entry
37c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
38c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long insn, fixup;
39c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru};
40c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
41c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int fixup_exception(struct pt_regs *regs);
42c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
43c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
44c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * These two are intentionally not defined anywhere - if the kernel
45c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * code generates any references to them, that's a bug.
46c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
47c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int __get_user_bad(void);
48c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int __put_user_bad(void);
49c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
50c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
51c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Note that this is actually 0x1,0000,0000
52c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
53c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define KERNEL_DS	0x00000000
54c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define get_ds()	(KERNEL_DS)
55c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
56c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_MMU
57c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
58c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define USER_DS		TASK_SIZE
59c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define get_fs()	(current_thread_info()->addr_limit)
60c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
61c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void set_fs(mm_segment_t fs)
62c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
63c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	current_thread_info()->addr_limit = fs;
64c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);
65c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
66c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
67c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define segment_eq(a,b)	((a) == (b))
68c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
69c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __addr_ok(addr) ({ \
70c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long flag; \
71c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__asm__("cmp %2, %0; movlo %0, #0" \
72c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		: "=&r" (flag) \
73c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		: "0" (current_thread_info()->addr_limit), "r" (addr) \
74c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		: "cc"); \
75c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	(flag == 0); })
76c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
77c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/* We use 33-bit arithmetic here... */
78c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __range_ok(addr,size) ({ \
79c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long flag, sum; \
80c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__chk_user_ptr(addr);	\
81c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \
82c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		: "=&r" (flag), "=&r" (sum) \
83c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		: "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \
84c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		: "cc"); \
85c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	flag; })
86c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
87c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
88c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * Single-value transfer routines.  They automatically use the right
89c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * size if we just have the right pointer type.  Note that the functions
90c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * which read from user space (*get_*) need to take care not to leak
91c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * kernel data even if the calling code is buggy and fails to check
92c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * the return value.  This means zeroing out the destination variable
93c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * or buffer on error.  Normally this is done out of line by the
94c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * fixup code, but there are a few places where it intrudes on the
95c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * main code path.  When we only write to user space, there is no
96c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * problem.
97c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
98c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int __get_user_1(void *);
99c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int __get_user_2(void *);
100c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int __get_user_4(void *);
101c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
102c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __get_user_x(__r2,__p,__e,__s,__i...)				\
103c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	   __asm__ __volatile__ (					\
104c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		__asmeq("%0", "r0") __asmeq("%1", "r2")			\
105c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		"bl	__get_user_" #__s				\
106c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		: "=&r" (__e), "=r" (__r2)				\
107c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		: "0" (__p)						\
108c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		: __i, "cc")
109c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
110c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define get_user(x,p)							\
111c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	({								\
112c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		const register typeof(*(p)) __user *__p asm("r0") = (p);\
113c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		register unsigned int __r2 asm("r2");			\
114c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		register int __e asm("r0");				\
115c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		switch (sizeof(*(__p))) {				\
116c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		case 1:							\
117c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			__get_user_x(__r2, __p, __e, 1, "lr");		\
118c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	       		break;						\
119c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		case 2:							\
120c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			__get_user_x(__r2, __p, __e, 2, "r3", "lr");	\
121c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			break;						\
122c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		case 4:							\
123c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	       		__get_user_x(__r2, __p, __e, 4, "lr");		\
124c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			break;						\
125c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		default: __e = __get_user_bad(); break;			\
126c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		}							\
127c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		x = (typeof(*(p))) __r2;				\
128c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		__e;							\
129c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	})
130c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
131c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int __put_user_1(void *, unsigned int);
132c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int __put_user_2(void *, unsigned int);
133c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int __put_user_4(void *, unsigned int);
134c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern int __put_user_8(void *, unsigned long long);
135c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
136c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __put_user_x(__r2,__p,__e,__s)					\
137c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	   __asm__ __volatile__ (					\
138c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		__asmeq("%0", "r0") __asmeq("%2", "r2")			\
139c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		"bl	__put_user_" #__s				\
140c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		: "=&r" (__e)						\
141c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		: "0" (__p), "r" (__r2)					\
142c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		: "ip", "lr", "cc")
143c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
144c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define put_user(x,p)							\
145c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	({								\
146c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		const register typeof(*(p)) __r2 asm("r2") = (x);	\
147c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		const register typeof(*(p)) __user *__p asm("r0") = (p);\
148c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		register int __e asm("r0");				\
149c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		switch (sizeof(*(__p))) {				\
150c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		case 1:							\
151c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			__put_user_x(__r2, __p, __e, 1);		\
152c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			break;						\
153c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		case 2:							\
154c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			__put_user_x(__r2, __p, __e, 2);		\
155c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			break;						\
156c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		case 4:							\
157c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			__put_user_x(__r2, __p, __e, 4);		\
158c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			break;						\
159c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		case 8:							\
160c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			__put_user_x(__r2, __p, __e, 8);		\
161c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru			break;						\
162c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		default: __e = __put_user_bad(); break;			\
163c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		}							\
164c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		__e;							\
165c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	})
166c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
167c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else /* CONFIG_MMU */
168c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
169c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
170c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * uClinux has only one addr space, so has simplified address limits.
171c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
172c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define USER_DS			KERNEL_DS
173c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
174c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define segment_eq(a,b)		(1)
175c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __addr_ok(addr)		(1)
176c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __range_ok(addr,size)	(0)
177c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define get_fs()		(KERNEL_DS)
178c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
179c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline void set_fs(mm_segment_t fs)
180c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
181c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
182c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
183c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define get_user(x,p)	__get_user(x,p)
184c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define put_user(x,p)	__put_user(x,p)
185c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
186c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif /* CONFIG_MMU */
187c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
188c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define access_ok(type,addr,size)	(__range_ok(addr,size) == 0)
189c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
190c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru/*
191c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * The "__xxx" versions of the user access functions do not verify the
192c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * address space - it must have been done previously with a separate
193c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * "access_ok()" call.
194c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru *
195c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * The "xxx_error" versions set the third argument to EFAULT if an
196c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * error occurs, and leave it unchanged on success.  Note that these
197c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru * versions are void (ie, don't return a value as such).
198c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru */
199c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __get_user(x,ptr)						\
200c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru({									\
201c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	long __gu_err = 0;						\
202c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__get_user_err((x),(ptr),__gu_err);				\
203c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__gu_err;							\
204c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru})
205c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
206c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __get_user_error(x,ptr,err)					\
207c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru({									\
208c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__get_user_err((x),(ptr),err);					\
209c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	(void) 0;							\
210c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru})
211c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
212c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __get_user_err(x,ptr,err)					\
213c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querudo {									\
214c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long __gu_addr = (unsigned long)(ptr);			\
215c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long __gu_val;						\
216c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__chk_user_ptr(ptr);						\
217c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	switch (sizeof(*(ptr))) {					\
218c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	case 1:	__get_user_asm_byte(__gu_val,__gu_addr,err);	break;	\
219c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	case 2:	__get_user_asm_half(__gu_val,__gu_addr,err);	break;	\
220c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	case 4:	__get_user_asm_word(__gu_val,__gu_addr,err);	break;	\
221c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	default: (__gu_val) = __get_user_bad();				\
222c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	}								\
223c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	(x) = (__typeof__(*(ptr)))__gu_val;				\
224c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} while (0)
225c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
226c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __get_user_asm_byte(x,addr,err)				\
227c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__asm__ __volatile__(					\
228c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"1:	ldrbt	%1,[%2],#0\n"				\
229c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"2:\n"							\
230c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.section .fixup,\"ax\"\n"			\
231c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.align	2\n"					\
232c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"3:	mov	%0, %3\n"				\
233c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	mov	%1, #0\n"				\
234c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	b	2b\n"					\
235c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.previous\n"					\
236c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.section __ex_table,\"a\"\n"			\
237c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.align	3\n"					\
238c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.long	1b, 3b\n"				\
239c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.previous"					\
240c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	: "+r" (err), "=&r" (x)					\
241c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	: "r" (addr), "i" (-EFAULT)				\
242c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	: "cc")
243c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
244c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef __ARMEB__
245c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __get_user_asm_half(x,__gu_addr,err)			\
246c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru({								\
247c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long __b1, __b2;				\
248c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__get_user_asm_byte(__b1, __gu_addr, err);		\
249c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__get_user_asm_byte(__b2, __gu_addr + 1, err);		\
250c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	(x) = __b1 | (__b2 << 8);				\
251c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru})
252c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
253c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __get_user_asm_half(x,__gu_addr,err)			\
254c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru({								\
255c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long __b1, __b2;				\
256c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__get_user_asm_byte(__b1, __gu_addr, err);		\
257c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__get_user_asm_byte(__b2, __gu_addr + 1, err);		\
258c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	(x) = (__b1 << 8) | __b2;				\
259c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru})
260c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
261c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
262c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __get_user_asm_word(x,addr,err)				\
263c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__asm__ __volatile__(					\
264c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"1:	ldrt	%1,[%2],#0\n"				\
265c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"2:\n"							\
266c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.section .fixup,\"ax\"\n"			\
267c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.align	2\n"					\
268c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"3:	mov	%0, %3\n"				\
269c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	mov	%1, #0\n"				\
270c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	b	2b\n"					\
271c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.previous\n"					\
272c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.section __ex_table,\"a\"\n"			\
273c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.align	3\n"					\
274c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.long	1b, 3b\n"				\
275c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.previous"					\
276c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	: "+r" (err), "=&r" (x)					\
277c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	: "r" (addr), "i" (-EFAULT)				\
278c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	: "cc")
279c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
280c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __put_user(x,ptr)						\
281c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru({									\
282c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	long __pu_err = 0;						\
283c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__put_user_err((x),(ptr),__pu_err);				\
284c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__pu_err;							\
285c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru})
286c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
287c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __put_user_error(x,ptr,err)					\
288c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru({									\
289c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__put_user_err((x),(ptr),err);					\
290c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	(void) 0;							\
291c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru})
292c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
293c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __put_user_err(x,ptr,err)					\
294c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querudo {									\
295c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long __pu_addr = (unsigned long)(ptr);			\
296c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__typeof__(*(ptr)) __pu_val = (x);				\
297c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__chk_user_ptr(ptr);						\
298c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	switch (sizeof(*(ptr))) {					\
299c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	case 1: __put_user_asm_byte(__pu_val,__pu_addr,err);	break;	\
300c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	case 2: __put_user_asm_half(__pu_val,__pu_addr,err);	break;	\
301c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	case 4: __put_user_asm_word(__pu_val,__pu_addr,err);	break;	\
302c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	case 8:	__put_user_asm_dword(__pu_val,__pu_addr,err);	break;	\
303c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	default: __put_user_bad();					\
304c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	}								\
305c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru} while (0)
306c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
307c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __put_user_asm_byte(x,__pu_addr,err)			\
308c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__asm__ __volatile__(					\
309c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"1:	strbt	%1,[%2],#0\n"				\
310c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"2:\n"							\
311c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.section .fixup,\"ax\"\n"			\
312c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.align	2\n"					\
313c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"3:	mov	%0, %3\n"				\
314c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	b	2b\n"					\
315c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.previous\n"					\
316c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.section __ex_table,\"a\"\n"			\
317c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.align	3\n"					\
318c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.long	1b, 3b\n"				\
319c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.previous"					\
320c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	: "+r" (err)						\
321c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	: "r" (x), "r" (__pu_addr), "i" (-EFAULT)		\
322c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	: "cc")
323c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
324c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef __ARMEB__
325c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __put_user_asm_half(x,__pu_addr,err)			\
326c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru({								\
327c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long __temp = (unsigned long)(x);		\
328c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__put_user_asm_byte(__temp, __pu_addr, err);		\
329c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__put_user_asm_byte(__temp >> 8, __pu_addr + 1, err);	\
330c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru})
331c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
332c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __put_user_asm_half(x,__pu_addr,err)			\
333c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru({								\
334c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long __temp = (unsigned long)(x);		\
335c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__put_user_asm_byte(__temp >> 8, __pu_addr, err);	\
336c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__put_user_asm_byte(__temp, __pu_addr + 1, err);	\
337c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru})
338c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
339c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
340c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __put_user_asm_word(x,__pu_addr,err)			\
341c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__asm__ __volatile__(					\
342c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"1:	strt	%1,[%2],#0\n"				\
343c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"2:\n"							\
344c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.section .fixup,\"ax\"\n"			\
345c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.align	2\n"					\
346c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"3:	mov	%0, %3\n"				\
347c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	b	2b\n"					\
348c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.previous\n"					\
349c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.section __ex_table,\"a\"\n"			\
350c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.align	3\n"					\
351c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.long	1b, 3b\n"				\
352c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.previous"					\
353c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	: "+r" (err)						\
354c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	: "r" (x), "r" (__pu_addr), "i" (-EFAULT)		\
355c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	: "cc")
356c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
357c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifndef __ARMEB__
358c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define	__reg_oper0	"%R2"
359c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define	__reg_oper1	"%Q2"
360c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
361c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define	__reg_oper0	"%Q2"
362c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define	__reg_oper1	"%R2"
363c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
364c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
365c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __put_user_asm_dword(x,__pu_addr,err)			\
366c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	__asm__ __volatile__(					\
367c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"1:	strt	" __reg_oper1 ", [%1], #4\n"		\
368c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"2:	strt	" __reg_oper0 ", [%1], #0\n"		\
369c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"3:\n"							\
370c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.section .fixup,\"ax\"\n"			\
371c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.align	2\n"					\
372c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"4:	mov	%0, %3\n"				\
373c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	b	3b\n"					\
374c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.previous\n"					\
375c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.section __ex_table,\"a\"\n"			\
376c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.align	3\n"					\
377c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.long	1b, 4b\n"				\
378c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.long	2b, 4b\n"				\
379c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	"	.previous"					\
380c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	: "+r" (err), "+r" (__pu_addr)				\
381c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	: "r" (x), "i" (-EFAULT)				\
382c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	: "cc")
383c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
384c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
385c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#ifdef CONFIG_MMU
386c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n);
387c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n);
388c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern unsigned long __clear_user(void __user *addr, unsigned long n);
389c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#else
390c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __copy_from_user(to,from,n)	(memcpy(to, (void __force *)from, n), 0)
391c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __copy_to_user(to,from,n)	(memcpy((void __force *)to, from, n), 0)
392c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __clear_user(addr,n)		(memset((void __force *)addr, 0, n), 0)
393c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif
394c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
395c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern unsigned long __strncpy_from_user(char *to, const char __user *from, unsigned long count);
396c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queruextern unsigned long __strnlen_user(const char __user *s, long n);
397c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
398c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
399c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
400c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	if (access_ok(VERIFY_READ, from, n))
401c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		n = __copy_from_user(to, from, n);
402c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	else /* security hole - plug it */
403c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		memzero(to, n);
404c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return n;
405c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
406c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
407c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
408c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
409c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	if (access_ok(VERIFY_WRITE, to, n))
410c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		n = __copy_to_user(to, from, n);
411c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return n;
412c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
413c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
414c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __copy_to_user_inatomic __copy_to_user
415c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define __copy_from_user_inatomic __copy_from_user
416c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
417c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline unsigned long clear_user(void __user *to, unsigned long n)
418c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
419c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	if (access_ok(VERIFY_WRITE, to, n))
420c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		n = __clear_user(to, n);
421c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return n;
422c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
423c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
424c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline long strncpy_from_user(char *dst, const char __user *src, long count)
425c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
426c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	long res = -EFAULT;
427c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	if (access_ok(VERIFY_READ, src, 1))
428c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		res = __strncpy_from_user(dst, src, count);
429c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return res;
430c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
431c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
432c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#define strlen_user(s)	strnlen_user(s, ~0UL >> 1)
433c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
434c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Querustatic inline long strnlen_user(const char __user *s, long n)
435c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru{
436c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	unsigned long res = 0;
437c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
438c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	if (__addr_ok(s))
439c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru		res = __strnlen_user(s, n);
440c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
441c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru	return res;
442c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru}
443c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru
444c559cd81139f97cecad1ad91a0b2e25a5936d53Jean-Baptiste Queru#endif /* _ASMARM_UACCESS_H */
445