aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze
diff options
context:
space:
mode:
authorMichal Simek <monstr@monstr.eu>2010-03-22 11:02:59 -0400
committerMichal Simek <monstr@monstr.eu>2010-04-01 02:38:21 -0400
commit527bdb52d50ddbc8dd64369e464d7a08bc7eb83c (patch)
treede24a85c279042092b55d2e2fe5263d76a20a6c2 /arch/microblaze
parent40e11e3380d4bd14bb3d85c7e7b863075a6a8d86 (diff)
microblaze: uaccess: fix clear_user for noMMU kernel
Previous patches fixed only MMU version and this is the first patch for noMMU kernel Signed-off-by: Michal Simek <monstr@monstr.eu>
Diffstat (limited to 'arch/microblaze')
-rw-r--r--arch/microblaze/include/asm/uaccess.h81
1 files changed, 36 insertions, 45 deletions
diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h
index fe954b394fd..1af92025fff 100644
--- a/arch/microblaze/include/asm/uaccess.h
+++ b/arch/microblaze/include/asm/uaccess.h
@@ -71,6 +71,9 @@ struct exception_table_entry {
71 unsigned long insn, fixup; 71 unsigned long insn, fixup;
72}; 72};
73 73
74/* Returns 0 if exception not found and fixup otherwise. */
75extern unsigned long search_exception_table(unsigned long);
76
74#ifndef CONFIG_MMU 77#ifndef CONFIG_MMU
75 78
76/* Check against bounds of physical memory */ 79/* Check against bounds of physical memory */
@@ -108,6 +111,39 @@ static inline int ___range_ok(unsigned long addr, unsigned long size)
108# define __EX_TABLE_SECTION ".section .discard,\"a\"\n" 111# define __EX_TABLE_SECTION ".section .discard,\"a\"\n"
109#endif 112#endif
110 113
114extern unsigned long __copy_tofrom_user(void __user *to,
115 const void __user *from, unsigned long size);
116
117/* Return: number of not copied bytes, i.e. 0 if OK or non-zero if fail. */
118static inline unsigned long __must_check __clear_user(void __user *to,
119 unsigned long n)
120{
121 /* normal memset with two words to __ex_table */
122 __asm__ __volatile__ ( \
123 "1: sb r0, %2, r0;" \
124 " addik %0, %0, -1;" \
125 " bneid %0, 1b;" \
126 " addik %2, %2, 1;" \
127 "2: " \
128 __EX_TABLE_SECTION \
129 ".word 1b,2b;" \
130 ".previous;" \
131 : "=r"(n) \
132 : "0"(n), "r"(to)
133 );
134 return n;
135}
136
137static inline unsigned long __must_check clear_user(void __user *to,
138 unsigned long n)
139{
140 might_sleep();
141 if (unlikely(!access_ok(VERIFY_WRITE, to, n)))
142 return n;
143
144 return __clear_user(to, n);
145}
146
111#ifndef CONFIG_MMU 147#ifndef CONFIG_MMU
112 148
113/* Undefined function to trigger linker error */ 149/* Undefined function to trigger linker error */
@@ -173,53 +209,11 @@ extern int bad_user_access_length(void);
173#define __copy_from_user_inatomic(to, from, n) \ 209#define __copy_from_user_inatomic(to, from, n) \
174 (__copy_from_user((to), (from), (n))) 210 (__copy_from_user((to), (from), (n)))
175 211
176#define __clear_user(addr, n) (memset((void *)(addr), 0, (n)), 0)
177
178/* stejne s MMU */
179static inline unsigned long clear_user(void *addr, unsigned long size)
180{
181 if (access_ok(VERIFY_WRITE, addr, size))
182 size = __clear_user(addr, size);
183 return size;
184}
185
186/* Returns 0 if exception not found and fixup otherwise. */
187extern unsigned long search_exception_table(unsigned long);
188
189extern long strncpy_from_user(char *dst, const char *src, long count); 212extern long strncpy_from_user(char *dst, const char *src, long count);
190extern long strnlen_user(const char *src, long count); 213extern long strnlen_user(const char *src, long count);
191 214
192#else /* CONFIG_MMU */ 215#else /* CONFIG_MMU */
193 216
194/* Return: number of not copied bytes, i.e. 0 if OK or non-zero if fail. */
195static inline unsigned long __must_check __clear_user(void __user *to,
196 unsigned long n)
197{
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 */ 217/* put_user and get_user macros */
224 218
225extern long __user_bad(void); 219extern long __user_bad(void);
@@ -372,9 +366,6 @@ extern long __user_bad(void);
372 ? __put_user((x), (ptr)) : -EFAULT; \ 366 ? __put_user((x), (ptr)) : -EFAULT; \
373}) 367})
374 368
375extern unsigned long __copy_tofrom_user(void __user *to,
376 const void __user *from, unsigned long size);
377
378#define __copy_from_user(to, from, n) \ 369#define __copy_from_user(to, from, n) \
379 __copy_tofrom_user((__force void __user *)(to), \ 370 __copy_tofrom_user((__force void __user *)(to), \
380 (void __user *)(from), (n)) 371 (void __user *)(from), (n))