On Wed, 1 Apr 2026 10:36:03 +0300 Mike Rapoport <[email protected]> wrote:

> Here's a fixup (it causes a conflict in patch 4 though).
> Andrew, I can send v4 if you prefer.

Looks pretty simple.  "userfaultfd: introduce mfill_get_vma() and
mfill_put_vma()" now leaves things like this:

retry:
        err = mfill_get_vma(&state);
        if (err)
                goto out;
        state.vma = dst_vma;

        /*
         * If this is a HUGETLB vma, pass off to appropriate routine
         */
        if (is_vm_hugetlb_page(state.vma))
                return mfill_atomic_hugetlb(ctx, state.vma, dst_start,
                                            src_start, len, flags);

        while (state.src_addr < src_start + len) {
                VM_WARN_ON_ONCE(state.dst_addr >= dst_start + len);

                err = mfill_establish_pmd(&state);
                if (err)
                        break;

                /*
                 * For shmem mappings, khugepaged is allowed to remove page
                 * tables under us; pte_offset_map_lock() will deal with that.
                 */

                err = mfill_atomic_pte(&state);
                cond_resched();

                if (unlikely(err == -ENOENT)) {
                        void *kaddr;

                        mfill_put_vma(&state);
                        VM_WARN_ON_ONCE(!state.folio);

                        kaddr = kmap_local_folio(state.folio, 0);
                        err = copy_from_user(kaddr,
                                             (const void __user 
*)state.src_addr,
                                             PAGE_SIZE);
                        kunmap_local(kaddr);
                        if (unlikely(err)) {
                                err = -EFAULT;
                                goto out;
                        }
                        flush_dcache_folio(state.folio);
                        goto retry;
                } else
                        VM_WARN_ON_ONCE(state.folio);

                if (!err) {
                        state.dst_addr += PAGE_SIZE;
                        state.src_addr += PAGE_SIZE;
                        copied += PAGE_SIZE;

                        if (fatal_signal_pending(current))
                                err = -EINTR;
                }
                if (err)
                        break;
        }


Reply via email to