s390/uaccess: shorten strncpy_from_user/strnlen_user
Always stay within page boundaries when copying from user within
strlen_user_mvcos()/strncpy_from_user_mvcos(). This allows to
shorten the code a bit and may prevent unnecessary faults, since
we copy quite large amounts of memory to kernel space.
Also directly call the mvcos variants of copy_from_user() to
avoid indirect branches.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c
index 2443ae4..7f3eb3d 100644
--- a/arch/s390/lib/uaccess_mvcos.c
+++ b/arch/s390/lib/uaccess_mvcos.c
@@ -162,19 +162,19 @@
static size_t strnlen_user_mvcos(size_t count, const char __user *src)
{
+ size_t done, len, offset, len_str;
char buf[256];
- int rc;
- size_t done, len, len_str;
done = 0;
do {
- len = min(count - done, (size_t) 256);
- rc = uaccess.copy_from_user(len, src + done, buf);
- if (unlikely(rc == len))
+ offset = (size_t)src & ~PAGE_MASK;
+ len = min(256UL, PAGE_SIZE - offset);
+ len = min(count - done, len);
+ if (copy_from_user_mvcos(len, src, buf))
return 0;
- len -= rc;
len_str = strnlen(buf, len);
done += len_str;
+ src += len_str;
} while ((len_str == len) && (done < count));
return done + 1;
}
@@ -182,18 +182,18 @@
static size_t strncpy_from_user_mvcos(size_t count, const char __user *src,
char *dst)
{
- int rc;
- size_t done, len, len_str;
+ size_t done, len, offset, len_str;
done = 0;
do {
- len = min(count - done, (size_t) 4096);
- rc = uaccess.copy_from_user(len, src + done, dst);
- if (unlikely(rc == len))
+ offset = (size_t)src & ~PAGE_MASK;
+ len = min(count - done, PAGE_SIZE - offset);
+ if (copy_from_user_mvcos(len, src, dst))
return -EFAULT;
- len -= rc;
len_str = strnlen(dst, len);
done += len_str;
+ src += len_str;
+ dst += len_str;
} while ((len_str == len) && (done < count));
return done;
}