mm: handle COW faults under the VMA lock
authorMatthew Wilcox (Oracle) <willy@infradead.org>
Fri, 6 Oct 2023 19:53:16 +0000 (20:53 +0100)
committerAndrew Morton <akpm@linux-foundation.org>
Wed, 18 Oct 2023 21:34:14 +0000 (14:34 -0700)
If the page is not currently present in the page tables, we need to call
the page fault handler to find out which page we're supposed to COW, so we
need to both check that there is already an anon_vma and that the fault
handler doesn't need the mmap_lock.

Link: https://lkml.kernel.org/r/20231006195318.4087158-5-willy@infradead.org
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: Suren Baghdasaryan <surenb@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/memory.c

index 7b240a67f207a814230f43a1ad5bf76b87182665..be9469a294136a4bc4f94b64db81d8598de0b78d 100644 (file)
@@ -4639,13 +4639,11 @@ static vm_fault_t do_cow_fault(struct vm_fault *vmf)
        struct vm_area_struct *vma = vmf->vma;
        vm_fault_t ret;
 
-       if (vmf->flags & FAULT_FLAG_VMA_LOCK) {
-               vma_end_read(vma);
-               return VM_FAULT_RETRY;
-       }
-
-       if (unlikely(anon_vma_prepare(vma)))
-               return VM_FAULT_OOM;
+       ret = vmf_can_call_fault(vmf);
+       if (!ret)
+               ret = vmf_anon_prepare(vmf);
+       if (ret)
+               return ret;
 
        vmf->cow_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vmf->address);
        if (!vmf->cow_page)