src_page = pmd_page(pmd);
        VM_BUG_ON_PAGE(!PageHead(src_page), src_page);
+
+       /*
+        * If this page is a potentially pinned page, split and retry the fault
+        * with smaller page size.  Normally this should not happen because the
+        * userspace should use MADV_DONTFORK upon pinned regions.  This is a
+        * best effort that the pinned pages won't be replaced by another
+        * random page during the coming copy-on-write.
+        */
+       if (unlikely(is_cow_mapping(vma->vm_flags) &&
+                    atomic_read(&src_mm->has_pinned) &&
+                    page_maybe_dma_pinned(src_page))) {
+               pte_free(dst_mm, pgtable);
+               spin_unlock(src_ptl);
+               spin_unlock(dst_ptl);
+               __split_huge_pmd(vma, src_pmd, addr, false, NULL);
+               return -EAGAIN;
+       }
+
        get_page(src_page);
        page_dup_rmap(src_page, true);
        add_mm_counter(dst_mm, MM_ANONPAGES, HPAGE_PMD_NR);
                /* No huge zero pud yet */
        }
 
+       /* Please refer to comments in copy_huge_pmd() */
+       if (unlikely(is_cow_mapping(vma->vm_flags) &&
+                    atomic_read(&src_mm->has_pinned) &&
+                    page_maybe_dma_pinned(pud_page(pud)))) {
+               spin_unlock(src_ptl);
+               spin_unlock(dst_ptl);
+               __split_huge_pud(vma, src_pud, addr);
+               return -EAGAIN;
+       }
+
        pudp_set_wrprotect(src_mm, addr, src_pud);
        pud = pud_mkold(pud_wrprotect(pud));
        set_pud_at(dst_mm, addr, dst_pud, pud);