diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2013-02-20 13:59:26 +0100 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-02-28 09:37:07 +0100 |
commit | d7b788cd06a3080ebf0b2f5f2e008d4fda2b336e (patch) | |
tree | 69441ca08ebf084277bc3d944bdde8d0ccdb8ecb /arch/s390 | |
parent | ea4da6eae393dbbb26800700a38cf1b32c9109fd (diff) | |
download | op-kernel-dev-d7b788cd06a3080ebf0b2f5f2e008d4fda2b336e.zip op-kernel-dev-d7b788cd06a3080ebf0b2f5f2e008d4fda2b336e.tar.gz |
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>
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/lib/uaccess_mvcos.c | 24 |
1 files changed, 12 insertions, 12 deletions
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 clear_user_mvcos(size_t size, void __user *to) 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 strnlen_user_mvcos(size_t count, const char __user *src) 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; } |