summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrea Arcangeli <aarcange@redhat.com>2017-02-22 15:42:43 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2017-02-22 16:41:28 -0800
commit0594f58dbd954f7747553c041d7cbbf9b6ef1947 (patch)
tree81328baeb50a904d058112628f80013f850dbf90
parent05ce77249d5068b057082d24ec22d3824f4816ac (diff)
downloadlinux-stable-0594f58dbd954f7747553c041d7cbbf9b6ef1947.tar.gz
linux-stable-0594f58dbd954f7747553c041d7cbbf9b6ef1947.tar.bz2
linux-stable-0594f58dbd954f7747553c041d7cbbf9b6ef1947.zip
userfaultfd: non-cooperative: avoid MADV_DONTNEED race condition
MADV_DONTNEED must be notified to userland before the pages are zapped. This allows userland to immediately stop adding pages to the userfaultfd ranges before the pages are actually zapped or there could be non-zeropage leftovers as result of concurrent UFFDIO_COPY run in between zap_page_range and madvise_userfault_dontneed (both MADV_DONTNEED and UFFDIO_COPY runs under the mmap_sem for reading, so they can run concurrently). Link: http://lkml.kernel.org/r/20161216144821.5183-15-aarcange@redhat.com Signed-off-by: Andrea Arcangeli <aarcange@redhat.com> Cc: "Dr. David Alan Gilbert" <dgilbert@redhat.com> Cc: Hillf Danton <hillf.zj@alibaba-inc.com> Cc: Michael Rapoport <RAPOPORT@il.ibm.com> Cc: Mike Kravetz <mike.kravetz@oracle.com> Cc: Mike Rapoport <rppt@linux.vnet.ibm.com> Cc: Pavel Emelyanov <xemul@parallels.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/madvise.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/mm/madvise.c b/mm/madvise.c
index 06ffb5a170de..ca75b8a01ba0 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -477,8 +477,8 @@ static long madvise_dontneed(struct vm_area_struct *vma,
if (vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_PFNMAP))
return -EINVAL;
- zap_page_range(vma, start, end - start, NULL);
madvise_userfault_dontneed(vma, prev, start, end);
+ zap_page_range(vma, start, end - start, NULL);
return 0;
}