The patch titled Subject: mm/gup: continue VM_FAULT_RETRY processing even for pre-faults has been removed from the -mm tree. Its filename was mm-gup-continue-vm_fault_retry-processing-event-for-pre-faults.patch This patch was dropped because it was merged into mainline or a subsystem tree ------------------------------------------------------ From: Mike Rapoport <rppt@xxxxxxxxxxxxx> Subject: mm/gup: continue VM_FAULT_RETRY processing even for pre-faults When get_user_pages*() is called with pages = NULL, the processing of VM_FAULT_RETRY terminates early without actually retrying to fault-in all the pages. If the pages in the requested range belong to a VMA that has userfaultfd registered, handle_userfault() returns VM_FAULT_RETRY *after* user space has populated the page, but for the gup pre-fault case there's no actual retry and the caller will get no pages although they are present. This issue was uncovered when running post-copy memory restore in CRIU after d9c9ce34ed5c ("x86/fpu: Fault-in user stack if copy_fpstate_to_sigframe() fails"). After this change, the copying of FPU state to the sigframe switched from copy_to_user() variants which caused a real page fault to get_user_pages() with pages parameter set to NULL. In post-copy mode of CRIU, the destination memory is managed with userfaultfd and lack of the retry for pre-fault case in get_user_pages() causes a crash of the restored process. Making the pre-fault behavior of get_user_pages() the same as the "normal" one fixes the issue. Link: http://lkml.kernel.org/r/1557844195-18882-1-git-send-email-rppt@xxxxxxxxxxxxx Fixes: d9c9ce34ed5c ("x86/fpu: Fault-in user stack if copy_fpstate_to_sigframe() fails") Signed-off-by: Mike Rapoport <rppt@xxxxxxxxxxxxx> Tested-by: Andrei Vagin <avagin@xxxxxxxxx> [https://travis-ci.org/avagin/linux/builds/533184940] Tested-by: Hugh Dickins <hughd@xxxxxxxxxx> Cc: Andrea Arcangeli <aarcange@xxxxxxxxxx> Cc: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx> Cc: Borislav Petkov <bp@xxxxxxx> Cc: Pavel Machek <pavel@xxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- mm/gup.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) --- a/mm/gup.c~mm-gup-continue-vm_fault_retry-processing-event-for-pre-faults +++ a/mm/gup.c @@ -1042,10 +1042,6 @@ static __always_inline long __get_user_p BUG_ON(ret >= nr_pages); } - if (!pages) - /* If it's a prefault don't insist harder */ - return ret; - if (ret > 0) { nr_pages -= ret; pages_done += ret; @@ -1061,8 +1057,12 @@ static __always_inline long __get_user_p pages_done = ret; break; } - /* VM_FAULT_RETRY triggered, so seek to the faulting offset */ - pages += ret; + /* + * VM_FAULT_RETRY triggered, so seek to the faulting offset. + * For the prefault case (!pages) we only update counts. + */ + if (likely(pages)) + pages += ret; start += ret << PAGE_SHIFT; /* @@ -1085,7 +1085,8 @@ static __always_inline long __get_user_p pages_done++; if (!nr_pages) break; - pages++; + if (likely(pages)) + pages++; start += PAGE_SIZE; } if (lock_dropped && *locked) { _ Patches currently in -mm which might be from rppt@xxxxxxxxxxxxx are arm-remove-arch_select_memory_model.patch s390-remove-arch_select_memory_model.patch sparc-remove-arch_select_memory_model.patch asm-generic-x86-introduce-generic-pte_allocfree_one.patch alpha-switch-to-generic-version-of-pte-allocation.patch arm-switch-to-generic-version-of-pte-allocation.patch arm64-switch-to-generic-version-of-pte-allocation.patch csky-switch-to-generic-version-of-pte-allocation.patch m68k-sun3-switch-to-generic-version-of-pte-allocation.patch mips-switch-to-generic-version-of-pte-allocation.patch nds32-switch-to-generic-version-of-pte-allocation.patch nios2-switch-to-generic-version-of-pte-allocation.patch parisc-switch-to-generic-version-of-pte-allocation.patch riscv-switch-to-generic-version-of-pte-allocation.patch um-switch-to-generic-version-of-pte-allocation.patch unicore32-switch-to-generic-version-of-pte-allocation.patch