aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2013-02-20 07:59:26 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-02-28 03:37:07 -0500
commitd7b788cd06a3080ebf0b2f5f2e008d4fda2b336e (patch)
tree69441ca08ebf084277bc3d944bdde8d0ccdb8ecb /arch
parentea4da6eae393dbbb26800700a38cf1b32c9109fd (diff)
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')
-rw-r--r--arch/s390/lib/uaccess_mvcos.c24
1 files changed, 12 insertions, 12 deletions
diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c
index 2443ae476e33..7f3eb3d56024 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)
162 162
163static size_t strnlen_user_mvcos(size_t count, const char __user *src) 163static size_t strnlen_user_mvcos(size_t count, const char __user *src)
164{ 164{
165 size_t done, len, offset, len_str;
165 char buf[256]; 166 char buf[256];
166 int rc;
167 size_t done, len, len_str;
168 167
169 done = 0; 168 done = 0;
170 do { 169 do {
171 len = min(count - done, (size_t) 256); 170 offset = (size_t)src & ~PAGE_MASK;
172 rc = uaccess.copy_from_user(len, src + done, buf); 171 len = min(256UL, PAGE_SIZE - offset);
173 if (unlikely(rc == len)) 172 len = min(count - done, len);
173 if (copy_from_user_mvcos(len, src, buf))
174 return 0; 174 return 0;
175 len -= rc;
176 len_str = strnlen(buf, len); 175 len_str = strnlen(buf, len);
177 done += len_str; 176 done += len_str;
177 src += len_str;
178 } while ((len_str == len) && (done < count)); 178 } while ((len_str == len) && (done < count));
179 return done + 1; 179 return done + 1;
180} 180}
@@ -182,18 +182,18 @@ static size_t strnlen_user_mvcos(size_t count, const char __user *src)
182static size_t strncpy_from_user_mvcos(size_t count, const char __user *src, 182static size_t strncpy_from_user_mvcos(size_t count, const char __user *src,
183 char *dst) 183 char *dst)
184{ 184{
185 int rc; 185 size_t done, len, offset, len_str;
186 size_t done, len, len_str;
187 186
188 done = 0; 187 done = 0;
189 do { 188 do {
190 len = min(count - done, (size_t) 4096); 189 offset = (size_t)src & ~PAGE_MASK;
191 rc = uaccess.copy_from_user(len, src + done, dst); 190 len = min(count - done, PAGE_SIZE - offset);
192 if (unlikely(rc == len)) 191 if (copy_from_user_mvcos(len, src, dst))
193 return -EFAULT; 192 return -EFAULT;
194 len -= rc;
195 len_str = strnlen(dst, len); 193 len_str = strnlen(dst, len);
196 done += len_str; 194 done += len_str;
195 src += len_str;
196 dst += len_str;
197 } while ((len_str == len) && (done < count)); 197 } while ((len_str == len) && (done < count));
198 return done; 198 return done;
199} 199}