2 * User address space access functions.
3 * The non inlined parts of asm-i386/uaccess.h are here.
5 * Copyright 1997 Andi Kleen <ak@muc.de>
6 * Copyright 1997 Linus Torvalds
8 #include <linux/config.h>
9 #include <asm/uaccess.h>
12 #ifdef CONFIG_X86_USE_3DNOW_AND_WORKS
15 __generic_copy_to_user(void *to, const void *from, unsigned long n)
18 if (access_ok(VERIFY_WRITE, to, n))
21 __copy_user(to,from,n);
23 mmx_copy_user(to,from,n);
29 __generic_copy_from_user(void *to, const void *from, unsigned long n)
32 if (access_ok(VERIFY_READ, from, n))
35 __copy_user_zeroing(to,from,n);
37 mmx_copy_user_zeroing(to, from, n);
47 __generic_copy_to_user(void *to, const void *from, unsigned long n)
51 if (access_ok(VERIFY_WRITE, to, n))
52 __copy_user(to,from,n);
57 __generic_copy_from_user(void *to, const void *from, unsigned long n)
61 if (access_ok(VERIFY_READ, from, n))
62 __copy_user_zeroing(to,from,n);
71 * Copy a null terminated string from userspace.
74 #define __do_strncpy_from_user(dst,src,count,res) \
76 int __d0, __d1, __d2; \
77 __asm__ __volatile__( \
82 " testb %%al,%%al\n" \
88 ".section .fixup,\"ax\"\n" \
92 ".section __ex_table,\"a\"\n" \
96 : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
98 : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
103 * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
104 * @dst: Destination address, in kernel space. This buffer must be at
105 * least @count bytes long.
106 * @src: Source address, in user space.
107 * @count: Maximum number of bytes to copy, including the trailing NUL.
109 * Copies a NUL-terminated string from userspace to kernel space.
110 * Caller must check the specified block with access_ok() before calling
113 * On success, returns the length of the string (not including the trailing
116 * If access to userspace fails, returns -EFAULT (some data may have been
119 * If @count is smaller than the length of the string, copies @count bytes
120 * and returns @count.
123 __strncpy_from_user(char *dst, const char *src, long count)
126 __do_strncpy_from_user(dst, src, count, res);
131 * strncpy_from_user: - Copy a NUL terminated string from userspace.
132 * @dst: Destination address, in kernel space. This buffer must be at
133 * least @count bytes long.
134 * @src: Source address, in user space.
135 * @count: Maximum number of bytes to copy, including the trailing NUL.
137 * Copies a NUL-terminated string from userspace to kernel space.
139 * On success, returns the length of the string (not including the trailing
142 * If access to userspace fails, returns -EFAULT (some data may have been
145 * If @count is smaller than the length of the string, copies @count bytes
146 * and returns @count.
149 strncpy_from_user(char *dst, const char *src, long count)
152 if (access_ok(VERIFY_READ, src, 1))
153 __do_strncpy_from_user(dst, src, count, res);
162 #define __do_clear_user(addr,size) \
165 __asm__ __volatile__( \
170 ".section .fixup,\"ax\"\n" \
171 "3: lea 0(%2,%0,4),%0\n" \
174 ".section __ex_table,\"a\"\n" \
179 : "=&c"(size), "=&D" (__d0) \
180 : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
184 * clear_user: - Zero a block of memory in user space.
185 * @to: Destination address, in user space.
186 * @n: Number of bytes to zero.
188 * Zero a block of memory in user space.
190 * Returns number of bytes that could not be cleared.
191 * On success, this will be zero.
194 clear_user(void *to, unsigned long n)
196 if (access_ok(VERIFY_WRITE, to, n))
197 __do_clear_user(to, n);
202 * __clear_user: - Zero a block of memory in user space, with less checking.
203 * @to: Destination address, in user space.
204 * @n: Number of bytes to zero.
206 * Zero a block of memory in user space. Caller must check
207 * the specified block with access_ok() before calling this function.
209 * Returns number of bytes that could not be cleared.
210 * On success, this will be zero.
213 __clear_user(void *to, unsigned long n)
215 __do_clear_user(to, n);
220 * strlen_user: - Get the size of a string in user space.
221 * @str: The string to measure.
222 * @n: The maximum valid length
224 * Get the size of a NUL-terminated string in user space.
226 * Returns the size of the string INCLUDING the terminating NUL.
227 * On exception, returns 0.
228 * If the string is too long, returns a value greater than @n.
230 long strnlen_user(const char *s, long n)
232 unsigned long mask = -__addr_ok(s);
233 unsigned long res, tmp;
235 __asm__ __volatile__(
244 ".section .fixup,\"ax\"\n"
245 "2: xorl %%eax,%%eax\n"
250 ".section __ex_table,\"a\"\n"
254 :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
255 :"0" (n), "1" (s), "2" (0), "3" (mask)