diff options
author | Michal Simek <monstr@monstr.eu> | 2010-03-22 11:02:59 -0400 |
---|---|---|
committer | Michal Simek <monstr@monstr.eu> | 2010-04-01 02:38:21 -0400 |
commit | 527bdb52d50ddbc8dd64369e464d7a08bc7eb83c (patch) | |
tree | de24a85c279042092b55d2e2fe5263d76a20a6c2 /arch/microblaze/include | |
parent | 40e11e3380d4bd14bb3d85c7e7b863075a6a8d86 (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/include')
-rw-r--r-- | arch/microblaze/include/asm/uaccess.h | 81 |
1 files changed, 36 insertions, 45 deletions
diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h index fe954b394fdc..1af92025fff9 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. */ | ||
75 | extern 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 | ||
114 | extern 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. */ | ||
118 | static 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 | |||
137 | static 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 */ | ||
179 | static 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. */ | ||
187 | extern unsigned long search_exception_table(unsigned long); | ||
188 | |||
189 | extern long strncpy_from_user(char *dst, const char *src, long count); | 212 | extern long strncpy_from_user(char *dst, const char *src, long count); |
190 | extern long strnlen_user(const char *src, long count); | 213 | extern 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. */ | ||
195 | static 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 | |||
214 | static 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 | ||
225 | extern long __user_bad(void); | 219 | extern 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 | ||
375 | extern 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)) |