aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-11-29 17:07:55 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-29 17:07:55 -0500
commit5d2a2dbbc1025dbf7998b9289574d9592b8f21cc (patch)
treeb4f3f45190b814b5196235c21f983fbc7878a47b
parentc9cfcddfd65735437a4cb8563d6b66a6da8a5ed6 (diff)
cow_user_page: fix page alignment
High Dickins points out that the user virtual address passed to the page fault handler isn't necessarily page-aligned. Also, add a comment on why the copy could fail for the user address case. Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--mm/memory.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/mm/memory.c b/mm/memory.c
index 74f95ae0510b..745b3482e6c2 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1394,8 +1394,15 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo
1394 */ 1394 */
1395 if (unlikely(!src)) { 1395 if (unlikely(!src)) {
1396 void *kaddr = kmap_atomic(dst, KM_USER0); 1396 void *kaddr = kmap_atomic(dst, KM_USER0);
1397 unsigned long left = __copy_from_user_inatomic(kaddr, (void __user *)va, PAGE_SIZE); 1397 void __user *uaddr = (void __user *)(va & PAGE_MASK);
1398 if (left) 1398
1399 /*
1400 * This really shouldn't fail, because the page is there
1401 * in the page tables. But it might just be unreadable,
1402 * in which case we just give up and fill the result with
1403 * zeroes.
1404 */
1405 if (__copy_from_user_inatomic(kaddr, uaddr, PAGE_SIZE))
1399 memset(kaddr, 0, PAGE_SIZE); 1406 memset(kaddr, 0, PAGE_SIZE);
1400 kunmap_atomic(kaddr, KM_USER0); 1407 kunmap_atomic(kaddr, KM_USER0);
1401 return; 1408 return;