* but what if the vma was unmerged while the page was swapped out?
  */
 struct page *ksm_might_need_to_copy(struct page *page,
-                       struct vm_area_struct *vma, unsigned long address);
+                       struct vm_area_struct *vma, unsigned long addr);
 
 void rmap_walk_ksm(struct folio *folio, struct rmap_walk_control *rwc);
 void folio_migrate_ksm(struct folio *newfolio, struct folio *folio);
 }
 
 static inline struct page *ksm_might_need_to_copy(struct page *page,
-                       struct vm_area_struct *vma, unsigned long address)
+                       struct vm_area_struct *vma, unsigned long addr)
 {
        return page;
 }
 
 }
 
 struct page *ksm_might_need_to_copy(struct page *page,
-                       struct vm_area_struct *vma, unsigned long address)
+                       struct vm_area_struct *vma, unsigned long addr)
 {
        struct folio *folio = page_folio(page);
        struct anon_vma *anon_vma = folio_anon_vma(folio);
-       struct page *new_page;
+       struct folio *new_folio;
 
-       if (PageKsm(page)) {
-               if (page_stable_node(page) &&
+       if (folio_test_large(folio))
+               return page;
+
+       if (folio_test_ksm(folio)) {
+               if (folio_stable_node(folio) &&
                    !(ksm_run & KSM_RUN_UNMERGE))
                        return page;    /* no need to copy it */
        } else if (!anon_vma) {
                return page;            /* no need to copy it */
-       } else if (page->index == linear_page_index(vma, address) &&
+       } else if (folio->index == linear_page_index(vma, addr) &&
                        anon_vma->root == vma->anon_vma->root) {
                return page;            /* still no need to copy it */
        }
        if (PageHWPoison(page))
                return ERR_PTR(-EHWPOISON);
-       if (!PageUptodate(page))
+       if (!folio_test_uptodate(folio))
                return page;            /* let do_swap_page report the error */
 
-       new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, address);
-       if (new_page &&
-           mem_cgroup_charge(page_folio(new_page), vma->vm_mm, GFP_KERNEL)) {
-               put_page(new_page);
-               new_page = NULL;
+       new_folio = vma_alloc_folio(GFP_HIGHUSER_MOVABLE, 0, vma, addr, false);
+       if (new_folio &&
+           mem_cgroup_charge(new_folio, vma->vm_mm, GFP_KERNEL)) {
+               folio_put(new_folio);
+               new_folio = NULL;
        }
-       if (new_page) {
-               if (copy_mc_user_highpage(new_page, page, address, vma)) {
-                       put_page(new_page);
+       if (new_folio) {
+               if (copy_mc_user_highpage(&new_folio->page, page, addr, vma)) {
+                       folio_put(new_folio);
                        memory_failure_queue(page_to_pfn(page), 0);
                        return ERR_PTR(-EHWPOISON);
                }
-               SetPageDirty(new_page);
-               __SetPageUptodate(new_page);
-               __SetPageLocked(new_page);
+               folio_set_dirty(new_folio);
+               __folio_mark_uptodate(new_folio);
+               __folio_set_locked(new_folio);
 #ifdef CONFIG_SWAP
                count_vm_event(KSM_SWPIN_COPY);
 #endif
        }
 
-       return new_page;
+       return new_folio ? &new_folio->page : NULL;
 }
 
 void rmap_walk_ksm(struct folio *folio, struct rmap_walk_control *rwc)