diff options
author | Naoya Horiguchi <n-horiguchi@ah.jp.nec.com> | 2010-05-11 14:06:55 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-11 17:33:42 -0700 |
commit | ab941e0fff3947b6dcc9c578d918d1bba54a6874 (patch) | |
tree | 5157de1b28370136fde227ecbd7fd2d38c15d30a /mm | |
parent | 4a6018f7f4f1075c1a5403b5ec0ee7262187b86c (diff) | |
download | linux-exynos-ab941e0fff3947b6dcc9c578d918d1bba54a6874.tar.gz linux-exynos-ab941e0fff3947b6dcc9c578d918d1bba54a6874.tar.bz2 linux-exynos-ab941e0fff3947b6dcc9c578d918d1bba54a6874.zip |
rmap: remove anon_vma check in page_address_in_vma()
Currently page_address_in_vma() compares vma->anon_vma and
page_anon_vma(page) for parameter check, but in 2.6.34 a vma can have
multiple anon_vmas with anon_vma_chain, so current check does not work.
(For anonymous page shared by multiple processes, some verified (page,vma)
pairs return -EFAULT wrongly.)
We can go to checking all anon_vmas in the "same_vma" chain, but it needs
to meet lock requirement. Instead, we can remove anon_vma check safely
because page_address_in_vma() assumes that page and vma are already
checked to belong to the identical process.
Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Reviewed-by: Rik van Riel <riel@redhat.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Mel Gorman <mel@csn.ul.ie>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/rmap.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/mm/rmap.c b/mm/rmap.c index 07fc94758799..0feeef860a8f 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -336,14 +336,13 @@ vma_address(struct page *page, struct vm_area_struct *vma) /* * At what user virtual address is page expected in vma? - * checking that the page matches the vma. + * Caller should check the page is actually part of the vma. */ unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma) { - if (PageAnon(page)) { - if (vma->anon_vma != page_anon_vma(page)) - return -EFAULT; - } else if (page->mapping && !(vma->vm_flags & VM_NONLINEAR)) { + if (PageAnon(page)) + ; + else if (page->mapping && !(vma->vm_flags & VM_NONLINEAR)) { if (!vma->vm_file || vma->vm_file->f_mapping != page->mapping) return -EFAULT; |