Commit ab941e0fff3947b6dcc9c578d918d1bba54a6874

Authored by Naoya Horiguchi
Committed by Linus Torvalds
1 parent 4a6018f7f4

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>

Showing 1 changed file with 4 additions and 5 deletions Side-by-side Diff

... ... @@ -336,14 +336,13 @@
336 336  
337 337 /*
338 338 * At what user virtual address is page expected in vma?
339   - * checking that the page matches the vma.
  339 + * Caller should check the page is actually part of the vma.
340 340 */
341 341 unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
342 342 {
343   - if (PageAnon(page)) {
344   - if (vma->anon_vma != page_anon_vma(page))
345   - return -EFAULT;
346   - } else if (page->mapping && !(vma->vm_flags & VM_NONLINEAR)) {
  343 + if (PageAnon(page))
  344 + ;
  345 + else if (page->mapping && !(vma->vm_flags & VM_NONLINEAR)) {
347 346 if (!vma->vm_file ||
348 347 vma->vm_file->f_mapping != page->mapping)
349 348 return -EFAULT;