aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze/include/asm
diff options
context:
space:
mode:
authorMichal Simek <monstr@monstr.eu>2010-03-05 10:50:01 -0500
committerMichal Simek <monstr@monstr.eu>2010-04-01 02:38:20 -0400
commit40b1156db09ab2df48aa4970ddf4a27a17246f1f (patch)
treeb9c3432203d89d0db621497c189b05c052990973 /arch/microblaze/include/asm
parent60a729f7bb936a9ab82b430de70a1952f560adf3 (diff)
microblaze: uaccess: fix clean user macro
This is the first patch which does uaccess unification. I choosed to do several patches to be able to use bisect in future if any fault happens. Signed-off-by: Michal Simek <monstr@monstr.eu>
Diffstat (limited to 'arch/microblaze/include/asm')
-rw-r--r--arch/microblaze/include/asm/uaccess.h89
1 files changed, 55 insertions, 34 deletions
diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h
index ce5defb259a4..fdb1c1cf51ad 100644
--- a/arch/microblaze/include/asm/uaccess.h
+++ b/arch/microblaze/include/asm/uaccess.h
@@ -71,8 +71,6 @@ struct exception_table_entry {
71 unsigned long insn, fixup; 71 unsigned long insn, fixup;
72}; 72};
73 73
74#define __clear_user(addr, n) (memset((void *)(addr), 0, (n)), 0)
75
76#ifndef CONFIG_MMU 74#ifndef CONFIG_MMU
77 75
78/* Check against bounds of physical memory */ 76/* Check against bounds of physical memory */
@@ -86,7 +84,31 @@ static inline int ___range_ok(unsigned long addr, unsigned long size)
86 ___range_ok((unsigned long)(addr), (unsigned long)(size)) 84 ___range_ok((unsigned long)(addr), (unsigned long)(size))
87 85
88#define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0) 86#define access_ok(type, addr, size) (__range_ok((addr), (size)) == 0)
89#define __access_ok(add, size) (__range_ok((addr), (size)) == 0) 87
88#else
89
90/*
91 * Address is valid if:
92 * - "addr", "addr + size" and "size" are all below the limit
93 */
94#define access_ok(type, addr, size) \
95 (get_fs().seg > (((unsigned long)(addr)) | \
96 (size) | ((unsigned long)(addr) + (size))))
97
98/* || printk("access_ok failed for %s at 0x%08lx (size %d), seg 0x%08x\n",
99 type?"WRITE":"READ",addr,size,get_fs().seg)) */
100
101#endif
102
103#ifdef CONFIG_MMU
104# define __FIXUP_SECTION ".section .fixup,\"ax\"\n"
105# define __EX_TABLE_SECTION ".section __ex_table,\"a\"\n"
106#else
107# define __FIXUP_SECTION ".section .discard,\"ax\"\n"
108# define __EX_TABLE_SECTION ".section .discard,\"a\"\n"
109#endif
110
111#ifndef CONFIG_MMU
90 112
91/* Undefined function to trigger linker error */ 113/* Undefined function to trigger linker error */
92extern int bad_user_access_length(void); 114extern int bad_user_access_length(void);
@@ -151,6 +173,9 @@ extern int bad_user_access_length(void);
151#define __copy_from_user_inatomic(to, from, n) \ 173#define __copy_from_user_inatomic(to, from, n) \
152 (__copy_from_user((to), (from), (n))) 174 (__copy_from_user((to), (from), (n)))
153 175
176#define __clear_user(addr, n) (memset((void *)(addr), 0, (n)), 0)
177
178/* stejne s MMU */
154static inline unsigned long clear_user(void *addr, unsigned long size) 179static inline unsigned long clear_user(void *addr, unsigned long size)
155{ 180{
156 if (access_ok(VERIFY_WRITE, addr, size)) 181 if (access_ok(VERIFY_WRITE, addr, size))
@@ -167,17 +192,6 @@ extern long strnlen_user(const char *src, long count);
167#else /* CONFIG_MMU */ 192#else /* CONFIG_MMU */
168 193
169/* 194/*
170 * Address is valid if:
171 * - "addr", "addr + size" and "size" are all below the limit
172 */
173#define access_ok(type, addr, size) \
174 (get_fs().seg > (((unsigned long)(addr)) | \
175 (size) | ((unsigned long)(addr) + (size))))
176
177/* || printk("access_ok failed for %s at 0x%08lx (size %d), seg 0x%08x\n",
178 type?"WRITE":"READ",addr,size,get_fs().seg)) */
179
180/*
181 * All the __XXX versions macros/functions below do not perform 195 * All the __XXX versions macros/functions below do not perform
182 * access checking. It is assumed that the necessary checks have been 196 * access checking. It is assumed that the necessary checks have been
183 * already performed before the finction (macro) is called. 197 * already performed before the finction (macro) is called.
@@ -297,27 +311,34 @@ __asm__ __volatile__ (" lwi %0, %1, 0; \
297 ); \ 311 ); \
298}) 312})
299 313
300/* 314/* Return: number of not copied bytes, i.e. 0 if OK or non-zero if fail. */
301 * Return: number of not copied bytes, i.e. 0 if OK or non-zero if fail. 315static inline unsigned long __must_check __clear_user(void __user *to,
302 */ 316 unsigned long n)
303static inline int clear_user(char *to, int size)
304{ 317{
305 if (size && access_ok(VERIFY_WRITE, to, size)) { 318 /* normal memset with two words to __ex_table */
306 __asm__ __volatile__ (" \ 319 __asm__ __volatile__ ( \
307 1: \ 320 "1: sb r0, %2, r0;" \
308 sb r0, %2, r0; \ 321 " addik %0, %0, -1;" \
309 addik %0, %0, -1; \ 322 " bneid %0, 1b;" \
310 bneid %0, 1b; \ 323 " addik %2, %2, 1;" \
311 addik %2, %2, 1; \ 324 "2: " \
312 2: \ 325 __EX_TABLE_SECTION \
313 .section __ex_table,\"a\"; \ 326 ".word 1b,2b;" \
314 .word 1b,2b; \ 327 ".previous;" \
315 .section .text;" \ 328 : "=r"(n) \
316 : "=r"(size) \ 329 : "0"(n), "r"(to)
317 : "0"(size), "r"(to) 330 );
318 ); 331 return n;
319 } 332}
320 return size; 333
334static inline unsigned long __must_check clear_user(void __user *to,
335 unsigned long n)
336{
337 might_sleep();
338 if (unlikely(!access_ok(VERIFY_WRITE, to, n)))
339 return n;
340
341 return __clear_user(to, n);
321} 342}
322 343
323#define __copy_from_user(to, from, n) copy_from_user((to), (from), (n)) 344#define __copy_from_user(to, from, n) copy_from_user((to), (from), (n))