}
 
 static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
-               unsigned long haddr)
+               unsigned long haddr, bool freeze)
 {
        struct mm_struct *mm = vma->vm_mm;
        struct page *page;
                 * transferred to avoid any possibility of altering
                 * permissions across VMAs.
                 */
-               entry = mk_pte(page + i, vma->vm_page_prot);
-               entry = maybe_mkwrite(pte_mkdirty(entry), vma);
-               if (!write)
-                       entry = pte_wrprotect(entry);
-               if (!young)
-                       entry = pte_mkold(entry);
+               if (freeze) {
+                       swp_entry_t swp_entry;
+                       swp_entry = make_migration_entry(page + i, write);
+                       entry = swp_entry_to_pte(swp_entry);
+               } else {
+                       entry = mk_pte(page + i, vma->vm_page_prot);
+                       entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+                       if (!write)
+                               entry = pte_wrprotect(entry);
+                       if (!young)
+                               entry = pte_mkold(entry);
+               }
                pte = pte_offset_map(&_pmd, haddr);
                BUG_ON(!pte_none(*pte));
                set_pte_at(mm, haddr, pte, entry);
        mmu_notifier_invalidate_range_start(mm, haddr, haddr + HPAGE_PMD_SIZE);
        ptl = pmd_lock(mm, pmd);
        if (likely(pmd_trans_huge(*pmd)))
-               __split_huge_pmd_locked(vma, pmd, haddr);
+               __split_huge_pmd_locked(vma, pmd, haddr, false);
        spin_unlock(ptl);
        mmu_notifier_invalidate_range_end(mm, haddr, haddr + HPAGE_PMD_SIZE);
 }