diff options
Diffstat (limited to 'drivers/char/mem.c')
-rw-r--r-- | drivers/char/mem.c | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index aaa9c24d4c14..c6b2fbc5ed47 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -154,6 +154,8 @@ static ssize_t read_mem(struct file * file, char __user * buf, | |||
154 | #endif | 154 | #endif |
155 | 155 | ||
156 | while (count > 0) { | 156 | while (count > 0) { |
157 | unsigned long remaining; | ||
158 | |||
157 | sz = size_inside_page(p, count); | 159 | sz = size_inside_page(p, count); |
158 | 160 | ||
159 | if (!range_is_allowed(p >> PAGE_SHIFT, count)) | 161 | if (!range_is_allowed(p >> PAGE_SHIFT, count)) |
@@ -168,12 +170,10 @@ static ssize_t read_mem(struct file * file, char __user * buf, | |||
168 | if (!ptr) | 170 | if (!ptr) |
169 | return -EFAULT; | 171 | return -EFAULT; |
170 | 172 | ||
171 | if (copy_to_user(buf, ptr, sz)) { | 173 | remaining = copy_to_user(buf, ptr, sz); |
172 | unxlate_dev_mem_ptr(p, ptr); | ||
173 | return -EFAULT; | ||
174 | } | ||
175 | |||
176 | unxlate_dev_mem_ptr(p, ptr); | 174 | unxlate_dev_mem_ptr(p, ptr); |
175 | if (remaining) | ||
176 | return -EFAULT; | ||
177 | 177 | ||
178 | buf += sz; | 178 | buf += sz; |
179 | p += sz; | 179 | p += sz; |
@@ -231,16 +231,14 @@ static ssize_t write_mem(struct file * file, const char __user * buf, | |||
231 | } | 231 | } |
232 | 232 | ||
233 | copied = copy_from_user(ptr, buf, sz); | 233 | copied = copy_from_user(ptr, buf, sz); |
234 | unxlate_dev_mem_ptr(p, ptr); | ||
234 | if (copied) { | 235 | if (copied) { |
235 | written += sz - copied; | 236 | written += sz - copied; |
236 | unxlate_dev_mem_ptr(p, ptr); | ||
237 | if (written) | 237 | if (written) |
238 | break; | 238 | break; |
239 | return -EFAULT; | 239 | return -EFAULT; |
240 | } | 240 | } |
241 | 241 | ||
242 | unxlate_dev_mem_ptr(p, ptr); | ||
243 | |||
244 | buf += sz; | 242 | buf += sz; |
245 | p += sz; | 243 | p += sz; |
246 | count -= sz; | 244 | count -= sz; |