From 9fb281590a03932274cebb48534e916ccbc7e622 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Wed, 1 Apr 2020 21:08:02 -0700 Subject: [PATCH] UPSTREAM: mm/gup: fix __get_user_pages() on fault retry of hugetlb When follow_hugetlb_page() returns with *locked==0, it means we've got a VM_FAULT_RETRY within the fauling process and we've released the mmap_sem. When that happens, we should stop and bail out. Signed-off-by: Peter Xu Signed-off-by: Andrew Morton Tested-by: Brian Geffon Cc: Andrea Arcangeli Cc: Bobby Powers Cc: David Hildenbrand Cc: Denis Plotnikov Cc: "Dr . David Alan Gilbert" Cc: Hugh Dickins Cc: Jerome Glisse Cc: Johannes Weiner Cc: "Kirill A . Shutemov" Cc: Martin Cracauer Cc: Marty McFadden Cc: Matthew Wilcox Cc: Maya Gokhale Cc: Mel Gorman Cc: Mike Kravetz Cc: Mike Rapoport Cc: Pavel Emelyanov Link: http://lkml.kernel.org/r/20200220155353.8676-3-peterx@redhat.com Signed-off-by: Linus Torvalds (cherry picked from commit ad415db817964e96df824e8bb1a861527f8012b6) Bug: 176847924 Signed-off-by: Kalesh Singh Change-Id: Ie7482106a07d4ee84b608f99192151d221605efb --- mm/gup.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/mm/gup.c b/mm/gup.c index 55255bcc3dac..60711d6b042a 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -845,6 +845,16 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, i = follow_hugetlb_page(mm, vma, pages, vmas, &start, &nr_pages, i, gup_flags, locked); + if (locked && *locked == 0) { + /* + * We've got a VM_FAULT_RETRY + * and we've lost mmap_sem. + * We must stop here. + */ + BUG_ON(gup_flags & FOLL_NOWAIT); + BUG_ON(ret != 0); + goto out; + } continue; } }