aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/include
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2012-05-25 00:02:48 -0400
committerPaul Mundt <lethal@linux-sh.org>2012-06-12 21:28:16 -0400
commit0e100e11bd73be4e28e457cf5ad49a6892d5d1fe (patch)
tree55e193c2f37f458bd51d363bac78e20897c86b49 /arch/sh/include
parent94fa83c424321189ca24fb6cb4c0d224cdedc72d (diff)
sh: switch to generic strncpy_from_user().
This kills off the special sh32/64 versions and adopts the generic version. It should be possible to optimize this for SH-4A unaligned loads, but this is a corner case that can be supported incrementally. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/include')
-rw-r--r--arch/sh/include/asm/uaccess.h35
-rw-r--r--arch/sh/include/asm/uaccess_32.h39
-rw-r--r--arch/sh/include/asm/uaccess_64.h2
3 files changed, 4 insertions, 72 deletions
diff --git a/arch/sh/include/asm/uaccess.h b/arch/sh/include/asm/uaccess.h
index 050f221fa89..3df7eee9c15 100644
--- a/arch/sh/include/asm/uaccess.h
+++ b/arch/sh/include/asm/uaccess.h
@@ -25,6 +25,8 @@
25 (__chk_user_ptr(addr), \ 25 (__chk_user_ptr(addr), \
26 __access_ok((unsigned long __force)(addr), (size))) 26 __access_ok((unsigned long __force)(addr), (size)))
27 27
28#define user_addr_max() (current_thread_info()->addr_limit.seg)
29
28/* 30/*
29 * Uh, these should become the main single-value transfer routines ... 31 * Uh, these should become the main single-value transfer routines ...
30 * They automatically use the right size if we just have the right 32 * They automatically use the right size if we just have the right
@@ -100,6 +102,8 @@ struct __large_struct { unsigned long buf[100]; };
100# include "uaccess_64.h" 102# include "uaccess_64.h"
101#endif 103#endif
102 104
105extern long strncpy_from_user(char *dest, const char __user *src, long count);
106
103/* Generic arbitrary sized copy. */ 107/* Generic arbitrary sized copy. */
104/* Return the number of bytes NOT copied */ 108/* Return the number of bytes NOT copied */
105__kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); 109__kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n);
@@ -137,37 +141,6 @@ __kernel_size_t __clear_user(void *addr, __kernel_size_t size);
137 __cl_size; \ 141 __cl_size; \
138}) 142})
139 143
140/**
141 * strncpy_from_user: - Copy a NUL terminated string from userspace.
142 * @dst: Destination address, in kernel space. This buffer must be at
143 * least @count bytes long.
144 * @src: Source address, in user space.
145 * @count: Maximum number of bytes to copy, including the trailing NUL.
146 *
147 * Copies a NUL-terminated string from userspace to kernel space.
148 *
149 * On success, returns the length of the string (not including the trailing
150 * NUL).
151 *
152 * If access to userspace fails, returns -EFAULT (some data may have been
153 * copied).
154 *
155 * If @count is smaller than the length of the string, copies @count bytes
156 * and returns @count.
157 */
158#define strncpy_from_user(dest,src,count) \
159({ \
160 unsigned long __sfu_src = (unsigned long)(src); \
161 int __sfu_count = (int)(count); \
162 long __sfu_res = -EFAULT; \
163 \
164 if (__access_ok(__sfu_src, __sfu_count)) \
165 __sfu_res = __strncpy_from_user((unsigned long)(dest), \
166 __sfu_src, __sfu_count); \
167 \
168 __sfu_res; \
169})
170
171static inline unsigned long 144static inline unsigned long
172copy_from_user(void *to, const void __user *from, unsigned long n) 145copy_from_user(void *to, const void __user *from, unsigned long n)
173{ 146{
diff --git a/arch/sh/include/asm/uaccess_32.h b/arch/sh/include/asm/uaccess_32.h
index ae0d24f6653..ef44d05bb63 100644
--- a/arch/sh/include/asm/uaccess_32.h
+++ b/arch/sh/include/asm/uaccess_32.h
@@ -170,45 +170,6 @@ __asm__ __volatile__( \
170 170
171extern void __put_user_unknown(void); 171extern void __put_user_unknown(void);
172 172
173static inline int
174__strncpy_from_user(unsigned long __dest, unsigned long __user __src, int __count)
175{
176 __kernel_size_t res;
177 unsigned long __dummy, _d, _s, _c;
178
179 __asm__ __volatile__(
180 "9:\n"
181 "mov.b @%2+, %1\n\t"
182 "cmp/eq #0, %1\n\t"
183 "bt/s 2f\n"
184 "1:\n"
185 "mov.b %1, @%3\n\t"
186 "dt %4\n\t"
187 "bf/s 9b\n\t"
188 " add #1, %3\n\t"
189 "2:\n\t"
190 "sub %4, %0\n"
191 "3:\n"
192 ".section .fixup,\"ax\"\n"
193 "4:\n\t"
194 "mov.l 5f, %1\n\t"
195 "jmp @%1\n\t"
196 " mov %9, %0\n\t"
197 ".balign 4\n"
198 "5: .long 3b\n"
199 ".previous\n"
200 ".section __ex_table,\"a\"\n"
201 " .balign 4\n"
202 " .long 9b,4b\n"
203 ".previous"
204 : "=r" (res), "=&z" (__dummy), "=r" (_s), "=r" (_d), "=r"(_c)
205 : "0" (__count), "2" (__src), "3" (__dest), "4" (__count),
206 "i" (-EFAULT)
207 : "memory", "t");
208
209 return res;
210}
211
212/* 173/*
213 * Return the size of a string (including the ending 0 even when we have 174 * Return the size of a string (including the ending 0 even when we have
214 * exceeded the maximum string length). 175 * exceeded the maximum string length).
diff --git a/arch/sh/include/asm/uaccess_64.h b/arch/sh/include/asm/uaccess_64.h
index 56fd20b8cdc..0042c9054b2 100644
--- a/arch/sh/include/asm/uaccess_64.h
+++ b/arch/sh/include/asm/uaccess_64.h
@@ -85,7 +85,5 @@ extern long __put_user_asm_q(void *, long);
85extern void __put_user_unknown(void); 85extern void __put_user_unknown(void);
86 86
87extern long __strnlen_user(const char *__s, long __n); 87extern long __strnlen_user(const char *__s, long __n);
88extern int __strncpy_from_user(unsigned long __dest,
89 unsigned long __user __src, int __count);
90 88
91#endif /* __ASM_SH_UACCESS_64_H */ 89#endif /* __ASM_SH_UACCESS_64_H */