]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - mm/mremap.c
Merge tag 'driver-core-4.13-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git...
[karo-tx-linux.git] / mm / mremap.c
index cd8a1b199ef9496ef63a50d97f92e648b8eecd58..3f23715d3c692770193ff99e707131d95369065c 100644 (file)
@@ -152,6 +152,7 @@ static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
        new_ptl = pte_lockptr(mm, new_pmd);
        if (new_ptl != old_ptl)
                spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
+       flush_tlb_batched_pending(vma->vm_mm);
        arch_enter_lazy_mmu_mode();
 
        for (; old_addr < old_end; old_pte++, old_addr += PAGE_SIZE,
@@ -428,6 +429,7 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr,
 static unsigned long mremap_to(unsigned long addr, unsigned long old_len,
                unsigned long new_addr, unsigned long new_len, bool *locked,
                struct vm_userfaultfd_ctx *uf,
+               struct list_head *uf_unmap_early,
                struct list_head *uf_unmap)
 {
        struct mm_struct *mm = current->mm;
@@ -446,7 +448,7 @@ static unsigned long mremap_to(unsigned long addr, unsigned long old_len,
        if (addr + old_len > new_addr && new_addr + new_len > addr)
                goto out;
 
-       ret = do_munmap(mm, new_addr, new_len, NULL);
+       ret = do_munmap(mm, new_addr, new_len, uf_unmap_early);
        if (ret)
                goto out;
 
@@ -514,6 +516,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
        unsigned long charged = 0;
        bool locked = false;
        struct vm_userfaultfd_ctx uf = NULL_VM_UFFD_CTX;
+       LIST_HEAD(uf_unmap_early);
        LIST_HEAD(uf_unmap);
 
        if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
@@ -541,7 +544,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
 
        if (flags & MREMAP_FIXED) {
                ret = mremap_to(addr, old_len, new_addr, new_len,
-                               &locked, &uf, &uf_unmap);
+                               &locked, &uf, &uf_unmap_early, &uf_unmap);
                goto out;
        }
 
@@ -621,6 +624,7 @@ out:
        up_write(&current->mm->mmap_sem);
        if (locked && new_len > old_len)
                mm_populate(new_addr + old_len, new_len - old_len);
+       userfaultfd_unmap_complete(mm, &uf_unmap_early);
        mremap_userfaultfd_complete(&uf, addr, new_addr, old_len);
        userfaultfd_unmap_complete(mm, &uf_unmap);
        return ret;