}
#ifdef CONFIG_HUGETLB_PAGE
+static
+ssize_t hugetlb_failed_do_unlock(struct userfaultfd_ctx *ctx,
+ struct vm_area_struct *dst, struct folio *folio,
+ unsigned long src_addr)
+{
+ up_read(&ctx->map_changing_lock);
+ uffd_mfill_unlock(dst);
+ VM_WARN_ON_ONCE(!folio);
+
+ return copy_folio_from_user(folio,(const void __user *)src_addr, true);
+}
+
/*
* mfill_atomic processing for HUGETLB vmas. Note that this routine is
* called with either vma-lock or mmap_lock held, it will release the lock
cond_resched();
if (unlikely(err == -ENOENT)) {
- up_read(&ctx->map_changing_lock);
- uffd_mfill_unlock(dst_vma);
- VM_WARN_ON_ONCE(!folio);
-
- err = copy_folio_from_user(folio,
- (const void __user *)src_addr, true);
+ err = hugetlb_failed_do_unlock(ctx, dst_vma, folio,
+ src_addr);
if (unlikely(err)) {
err = -EFAULT;
goto out;