diff options
-rw-r--r-- | arch/s390/lib/uaccess_pt.c | 34 | ||||
-rw-r--r-- | arch/s390/lib/uaccess_std.c | 46 |
2 files changed, 34 insertions, 46 deletions
diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c index c1aaf22c326b..304e07086ab3 100644 --- a/arch/s390/lib/uaccess_pt.c +++ b/arch/s390/lib/uaccess_pt.c | |||
@@ -202,27 +202,29 @@ fault: | |||
202 | static size_t strncpy_from_user_pt(size_t count, const char __user *src, | 202 | static size_t strncpy_from_user_pt(size_t count, const char __user *src, |
203 | char *dst) | 203 | char *dst) |
204 | { | 204 | { |
205 | size_t n = strnlen_user_pt(count, src); | 205 | size_t done, len, offset, len_str; |
206 | 206 | ||
207 | if (unlikely(!count)) | 207 | if (unlikely(!count)) |
208 | return 0; | 208 | return 0; |
209 | if (!n) | ||
210 | return -EFAULT; | ||
211 | if (n > count) | ||
212 | n = count; | ||
213 | if (segment_eq(get_fs(), KERNEL_DS)) { | 209 | if (segment_eq(get_fs(), KERNEL_DS)) { |
214 | memcpy(dst, (const char __kernel __force *) src, n); | 210 | len = strnlen((const char __kernel __force *) src, count) + 1; |
215 | if (dst[n-1] == '\0') | 211 | if (len > count) |
216 | return n-1; | 212 | len = count; |
217 | else | 213 | memcpy(dst, (const char __kernel __force *) src, len); |
218 | return n; | 214 | return (dst[len - 1] == '\0') ? len - 1 : len; |
219 | } | 215 | } |
220 | if (__user_copy_pt((unsigned long) src, dst, n, 0)) | 216 | done = 0; |
221 | return -EFAULT; | 217 | do { |
222 | if (dst[n-1] == '\0') | 218 | offset = (size_t)src & ~PAGE_MASK; |
223 | return n-1; | 219 | len = min(count - done, PAGE_SIZE - offset); |
224 | else | 220 | if (__user_copy_pt((unsigned long) src, dst, len, 0)) |
225 | return n; | 221 | return -EFAULT; |
222 | len_str = strnlen(dst, len); | ||
223 | done += len_str; | ||
224 | src += len_str; | ||
225 | dst += len_str; | ||
226 | } while ((len_str == len) && (done < count)); | ||
227 | return done; | ||
226 | } | 228 | } |
227 | 229 | ||
228 | static size_t copy_in_user_pt(size_t n, void __user *to, | 230 | static size_t copy_in_user_pt(size_t n, void __user *to, |
diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c index 79c6c7d76e08..4a75d475b06a 100644 --- a/arch/s390/lib/uaccess_std.c +++ b/arch/s390/lib/uaccess_std.c | |||
@@ -206,38 +206,24 @@ size_t strnlen_user_std(size_t size, const char __user *src) | |||
206 | return size; | 206 | return size; |
207 | } | 207 | } |
208 | 208 | ||
209 | size_t strncpy_from_user_std(size_t size, const char __user *src, char *dst) | 209 | size_t strncpy_from_user_std(size_t count, const char __user *src, char *dst) |
210 | { | 210 | { |
211 | register unsigned long reg0 asm("0") = 0UL; | 211 | size_t done, len, offset, len_str; |
212 | unsigned long tmp1, tmp2; | ||
213 | 212 | ||
214 | asm volatile( | 213 | if (unlikely(!count)) |
215 | " la %3,0(%1)\n" | 214 | return 0; |
216 | " la %4,0(%0,%1)\n" | 215 | done = 0; |
217 | " sacf 256\n" | 216 | do { |
218 | "0: srst %4,%3\n" | 217 | offset = (size_t)src & ~PAGE_MASK; |
219 | " jo 0b\n" | 218 | len = min(count - done, PAGE_SIZE - offset); |
220 | " sacf 0\n" | 219 | if (copy_from_user_std(len, src, dst)) |
221 | " la %0,0(%4)\n" | 220 | return -EFAULT; |
222 | " jh 1f\n" /* found \0 in string ? */ | 221 | len_str = strnlen(dst, len); |
223 | " "AHI" %4,1\n" /* include \0 in copy */ | 222 | done += len_str; |
224 | "1:"SLR" %0,%1\n" /* %0 = return length (without \0) */ | 223 | src += len_str; |
225 | " "SLR" %4,%1\n" /* %4 = copy length (including \0) */ | 224 | dst += len_str; |
226 | "2: mvcp 0(%4,%2),0(%1),%5\n" | 225 | } while ((len_str == len) && (done < count)); |
227 | " jz 9f\n" | 226 | return done; |
228 | "3:"AHI" %4,-256\n" | ||
229 | " la %1,256(%1)\n" | ||
230 | " la %2,256(%2)\n" | ||
231 | "4: mvcp 0(%4,%2),0(%1),%5\n" | ||
232 | " jnz 3b\n" | ||
233 | " j 9f\n" | ||
234 | "7: sacf 0\n" | ||
235 | "8:"LHI" %0,%6\n" | ||
236 | "9:\n" | ||
237 | EX_TABLE(0b,7b) EX_TABLE(2b,8b) EX_TABLE(4b,8b) | ||
238 | : "+a" (size), "+a" (src), "+d" (dst), "=a" (tmp1), "=a" (tmp2) | ||
239 | : "d" (reg0), "K" (-EFAULT) : "cc", "memory"); | ||
240 | return size; | ||
241 | } | 227 | } |
242 | 228 | ||
243 | #define __futex_atomic_op(insn, ret, oldval, newval, uaddr, oparg) \ | 229 | #define __futex_atomic_op(insn, ret, oldval, newval, uaddr, oparg) \ |