aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze/include
diff options
context:
space:
mode:
authorMichal Simek <monstr@monstr.eu>2010-03-22 10:46:56 -0400
committerMichal Simek <monstr@monstr.eu>2010-04-01 02:38:20 -0400
commit0dcb409de73edeb221aed38d9ff8640cf41ff0de (patch)
treed58a50ff8fe3e17b43c3db60cb02c6b71d2672ed /arch/microblaze/include
parent8b651aa4a7c047b848f3a7bdf0aba9449e6dc3d3 (diff)
microblaze: uaccess: sync put/get/clear_user macros
Add macro description and resort. Signed-off-by: Michal Simek <monstr@monstr.eu>
Diffstat (limited to 'arch/microblaze/include')
-rw-r--r--arch/microblaze/include/asm/uaccess.h106
1 files changed, 69 insertions, 37 deletions
diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h
index 1e8fa4b76115..6bb9b8fb6655 100644
--- a/arch/microblaze/include/asm/uaccess.h
+++ b/arch/microblaze/include/asm/uaccess.h
@@ -191,11 +191,38 @@ extern long strnlen_user(const char *src, long count);
191 191
192#else /* CONFIG_MMU */ 192#else /* CONFIG_MMU */
193 193
194/* 194/* Return: number of not copied bytes, i.e. 0 if OK or non-zero if fail. */
195 * All the __XXX versions macros/functions below do not perform 195static inline unsigned long __must_check __clear_user(void __user *to,
196 * access checking. It is assumed that the necessary checks have been 196 unsigned long n)
197 * already performed before the finction (macro) is called. 197{
198 */ 198 /* normal memset with two words to __ex_table */
199 __asm__ __volatile__ ( \
200 "1: sb r0, %2, r0;" \
201 " addik %0, %0, -1;" \
202 " bneid %0, 1b;" \
203 " addik %2, %2, 1;" \
204 "2: " \
205 __EX_TABLE_SECTION \
206 ".word 1b,2b;" \
207 ".previous;" \
208 : "=r"(n) \
209 : "0"(n), "r"(to)
210 );
211 return n;
212}
213
214static inline unsigned long __must_check clear_user(void __user *to,
215 unsigned long n)
216{
217 might_sleep();
218 if (unlikely(!access_ok(VERIFY_WRITE, to, n)))
219 return n;
220 return __clear_user(to, n);
221}
222
223/* put_user and get_user macros */
224
225extern long __user_bad(void);
199 226
200#define __get_user_asm(insn, __gu_ptr, __gu_val, __gu_err) \ 227#define __get_user_asm(insn, __gu_ptr, __gu_val, __gu_err) \
201({ \ 228({ \
@@ -231,18 +258,53 @@ extern long strnlen_user(const char *src, long count);
231 __get_user_asm("lw", (ptr), __gu_val, __gu_err); \ 258 __get_user_asm("lw", (ptr), __gu_val, __gu_err); \
232 break; \ 259 break; \
233 default: \ 260 default: \
234 __gu_val = 0; __gu_err = -EINVAL; \ 261 /* __gu_val = 0; __gu_err = -EINVAL;*/ __gu_err = __user_bad();\
235 } \ 262 } \
236 x = (__typeof__(*(ptr))) __gu_val; \ 263 x = (__typeof__(*(ptr))) __gu_val; \
237 __gu_err; \ 264 __gu_err; \
238}) 265})
239 266
267/**
268 * get_user: - Get a simple variable from user space.
269 * @x: Variable to store result.
270 * @ptr: Source address, in user space.
271 *
272 * Context: User context only. This function may sleep.
273 *
274 * This macro copies a single simple variable from user space to kernel
275 * space. It supports simple types like char and int, but not larger
276 * data types like structures or arrays.
277 *
278 * @ptr must have pointer-to-simple-variable type, and the result of
279 * dereferencing @ptr must be assignable to @x without a cast.
280 *
281 * Returns zero on success, or -EFAULT on error.
282 * On error, the variable @x is set to zero.
283 */
284
240#define get_user(x, ptr) \ 285#define get_user(x, ptr) \
241({ \ 286({ \
242 access_ok(VERIFY_READ, (ptr), sizeof(*(ptr))) \ 287 access_ok(VERIFY_READ, (ptr), sizeof(*(ptr))) \
243 ? __get_user((x), (ptr)) : -EFAULT; \ 288 ? __get_user((x), (ptr)) : -EFAULT; \
244}) 289})
245 290
291/**
292 * put_user: - Write a simple value into user space.
293 * @x: Value to copy to user space.
294 * @ptr: Destination address, in user space.
295 *
296 * Context: User context only. This function may sleep.
297 *
298 * This macro copies a single simple value from kernel space to user
299 * space. It supports simple types like char and int, but not larger
300 * data types like structures or arrays.
301 *
302 * @ptr must have pointer-to-simple-variable type, and @x must be assignable
303 * to the result of dereferencing @ptr.
304 *
305 * Returns zero on success, or -EFAULT on error.
306 */
307
246#define __put_user_asm(insn, __gu_ptr, __gu_val, __gu_err) \ 308#define __put_user_asm(insn, __gu_ptr, __gu_val, __gu_err) \
247({ \ 309({ \
248 __asm__ __volatile__ ( \ 310 __asm__ __volatile__ ( \
@@ -299,7 +361,7 @@ extern long strnlen_user(const char *src, long count);
299 __put_user_asm_8((ptr), __gu_val, __gu_err); \ 361 __put_user_asm_8((ptr), __gu_val, __gu_err); \
300 break; \ 362 break; \
301 default: \ 363 default: \
302 __gu_err = -EINVAL; \ 364 /*__gu_err = -EINVAL;*/ __gu_err = __user_bad(); \
303 } \ 365 } \
304 __gu_err; \ 366 __gu_err; \
305}) 367})
@@ -310,36 +372,6 @@ extern long strnlen_user(const char *src, long count);
310 ? __put_user((x), (ptr)) : -EFAULT; \ 372 ? __put_user((x), (ptr)) : -EFAULT; \
311}) 373})
312 374
313/* Return: number of not copied bytes, i.e. 0 if OK or non-zero if fail. */
314static inline unsigned long __must_check __clear_user(void __user *to,
315 unsigned long n)
316{
317 /* normal memset with two words to __ex_table */
318 __asm__ __volatile__ ( \
319 "1: sb r0, %2, r0;" \
320 " addik %0, %0, -1;" \
321 " bneid %0, 1b;" \
322 " addik %2, %2, 1;" \
323 "2: " \
324 __EX_TABLE_SECTION \
325 ".word 1b,2b;" \
326 ".previous;" \
327 : "=r"(n) \
328 : "0"(n), "r"(to)
329 );
330 return n;
331}
332
333static inline unsigned long __must_check clear_user(void __user *to,
334 unsigned long n)
335{
336 might_sleep();
337 if (unlikely(!access_ok(VERIFY_WRITE, to, n)))
338 return n;
339
340 return __clear_user(to, n);
341}
342
343#define __copy_from_user(to, from, n) copy_from_user((to), (from), (n)) 375#define __copy_from_user(to, from, n) copy_from_user((to), (from), (n))
344#define __copy_from_user_inatomic(to, from, n) \ 376#define __copy_from_user_inatomic(to, from, n) \
345 copy_from_user((to), (from), (n)) 377 copy_from_user((to), (from), (n))