mirror of
https://github.com/adulau/aha.git
synced 2024-12-29 12:16:20 +00:00
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>
This commit is contained in:
parent
c9cfcddfd6
commit
5d2a2dbbc1
1 changed files with 9 additions and 2 deletions
11
mm/memory.c
11
mm/memory.c
|
@ -1394,8 +1394,15 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo
|
||||||
*/
|
*/
|
||||||
if (unlikely(!src)) {
|
if (unlikely(!src)) {
|
||||||
void *kaddr = kmap_atomic(dst, KM_USER0);
|
void *kaddr = kmap_atomic(dst, KM_USER0);
|
||||||
unsigned long left = __copy_from_user_inatomic(kaddr, (void __user *)va, PAGE_SIZE);
|
void __user *uaddr = (void __user *)(va & PAGE_MASK);
|
||||||
if (left)
|
|
||||||
|
/*
|
||||||
|
* This really shouldn't fail, because the page is there
|
||||||
|
* in the page tables. But it might just be unreadable,
|
||||||
|
* in which case we just give up and fill the result with
|
||||||
|
* zeroes.
|
||||||
|
*/
|
||||||
|
if (__copy_from_user_inatomic(kaddr, uaddr, PAGE_SIZE))
|
||||||
memset(kaddr, 0, PAGE_SIZE);
|
memset(kaddr, 0, PAGE_SIZE);
|
||||||
kunmap_atomic(kaddr, KM_USER0);
|
kunmap_atomic(kaddr, KM_USER0);
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in a new issue