// SPDX-License-Identifier: GPL-2.0
/*
 * Device Memory Migration functionality.
 *
 * Originally written by Jérôme Glisse.
 */
#include <linux/export.h>
#include <linux/memremap.h>
#include <linux/migrate.h>
#include <linux/mm.h>
#include <linux/mm_inline.h>
#include <linux/mmu_notifier.h>
#include <linux/oom.h>
#include <linux/pagewalk.h>
#include <linux/rmap.h>
#include <linux/leafops.h>
#include <linux/pgalloc.h>
#include <asm/tlbflush.h>
#include "internal.h"

static int migrate_vma_collect_skip(unsigned long start,
				    unsigned long end,
				    struct mm_walk *walk)
{
	struct migrate_vma *migrate = walk->private;
	unsigned long addr;

	for (addr = start; addr < end; addr += PAGE_SIZE) {
		migrate->dst[migrate->npages] = 0;
		migrate->src[migrate->npages++] = 0;
	}

	return 0;
}

static int migrate_vma_collect_hole(unsigned long start,
				    unsigned long end,
				    __always_unused int depth,
				    struct mm_walk *walk)
{
	struct migrate_vma *migrate = walk->private;
	unsigned long addr;

	/* Only allow populating anonymous memory. */
	if (!vma_is_anonymous(walk->vma))
		return migrate_vma_collect_skip(start, end, walk);

	if (thp_migration_supported() &&
		(migrate->flags & MIGRATE_VMA_SELECT_COMPOUND) &&
		(IS_ALIGNED(start, HPAGE_PMD_SIZE) &&
		 IS_ALIGNED(end, HPAGE_PMD_SIZE))) {
		migrate->src[migrate->npages] = MIGRATE_PFN_MIGRATE |
						MIGRATE_PFN_COMPOUND;
		migrate->dst[migrate->npages] = 0;
		migrate->npages++;
		migrate->cpages++;

		/*
		 * Collect the remaining entries as holes, in case we
		 * need to split later
		 */
		return migrate_vma_collect_skip(start + PAGE_SIZE, end, walk);
	}

	for (addr = start; addr < end; addr += PAGE_SIZE) {
		migrate->src[migrate->npages] = MIGRATE_PFN_MIGRATE;
		migrate->dst[migrate->npages] = 0;
		migrate->npages++;
		migrate->cpages++;
	}

	return 0;
}

/**
 * migrate_vma_split_folio() - Helper function to split a THP folio
 * @folio: the folio to split
 * @fault_page: struct page associated with the fault if any
 *
 * Returns 0 on success
 */
static int migrate_vma_split_folio(struct folio *folio,
				   struct page *fault_page)
{
	int ret;
	struct folio *fault_folio = fault_page ? page_folio(fault_page) : NULL;
	struct folio *new_fault_folio = NULL;

	if (folio != fault_folio) {
		folio_get(folio);
		folio_lock(folio);
	}

	ret = split_folio(folio);
	if (ret) {
		if (folio != fault_folio) {
			folio_unlock(folio);
			folio_put(folio);
		}
		return ret;
	}

	new_fault_folio = fault_page ? page_folio(fault_page) : NULL;

	/*
	 * Ensure the lock is held on the correct
	 * folio after the split
	 */
	if (!new_fault_folio) {
		folio_unlock(folio);
		folio_put(folio);
	} else if (folio != new_fault_folio) {
		if (new_fault_folio != fault_folio) {
			folio_get(new_fault_folio);
			folio_lock(new_fault_folio);
		}
		folio_unlock(folio);
		folio_put(folio);
	}

	return 0;
}

/** migrate_vma_collect_huge_pmd - collect THP pages without splitting the
 * folio for device private pages.
 * @pmdp: pointer to pmd entry
 * @start: start address of the range for migration
 * @end: end address of the range for migration
 * @walk: mm_walk callback structure
 * @fault_folio: folio associated with the fault if any
 *
 * Collect the huge pmd entry at @pmdp for migration and set the
 * MIGRATE_PFN_COMPOUND flag in the migrate src entry to indicate that
 * migration will occur at HPAGE_PMD granularity
 */
static int migrate_vma_collect_huge_pmd(pmd_t *pmdp, unsigned long start,
					unsigned long end, struct mm_walk *walk,
					struct folio *fault_folio)
{
	struct mm_struct *mm = walk->mm;
	struct folio *folio;
	struct migrate_vma *migrate = walk->private;
	spinlock_t *ptl;
	int ret;
	unsigned long write = 0;

	ptl = pmd_lock(mm, pmdp);
	if (pmd_none(*pmdp)) {
		spin_unlock(ptl);
		return migrate_vma_collect_hole(start, end, -1, walk);
	}

	if (pmd_trans_huge(*pmdp)) {
		if (!(migrate->flags & MIGRATE_VMA_SELECT_SYSTEM)) {
			spin_unlock(ptl);
			return migrate_vma_collect_skip(start, end, walk);
		}

		folio = pmd_folio(*pmdp);
		if (is_huge_zero_folio(folio)) {
			spin_unlock(ptl);
			return migrate_vma_collect_hole(start, end, -1, walk);
		}
		if (pmd_write(*pmdp))
			write = MIGRATE_PFN_WRITE;
	} else if (!pmd_present(*pmdp)) {
		const softleaf_t entry = softleaf_from_pmd(*pmdp);

		folio = softleaf_to_folio(entry);

		if (!softleaf_is_device_private(entry) ||
			!(migrate->flags & MIGRATE_VMA_SELECT_DEVICE_PRIVATE) ||
			(folio->pgmap->owner != migrate->pgmap_owner)) {
			spin_unlock(ptl);
			return migrate_vma_collect_skip(start, end, walk);
		}

		if (softleaf_is_device_private_write(entry))
			write = MIGRATE_PFN_WRITE;
	} else {
		spin_unlock(ptl);
		return -EAGAIN;
	}

	folio_get(folio);
	if (folio != fault_folio && unlikely(!folio_trylock(folio))) {
		spin_unlock(ptl);
		folio_put(folio);
		return migrate_vma_collect_skip(start, end, walk);
	}

	if (thp_migration_supported() &&
		(migrate->flags & MIGRATE_VMA_SELECT_COMPOUND) &&
		(IS_ALIGNED(start, HPAGE_PMD_SIZE) &&
		 IS_ALIGNED(end, HPAGE_PMD_SIZE))) {

		struct page_vma_mapped_walk pvmw = {
			.ptl = ptl,
			.address = start,
			.pmd = pmdp,
			.vma = walk->vma,
		};

		unsigned long pfn = page_to_pfn(folio_page(folio, 0));

		migrate->src[migrate->npages] = migrate_pfn(pfn) | write
						| MIGRATE_PFN_MIGRATE
						| MIGRATE_PFN_COMPOUND;
		migrate->dst[migrate->npages++] = 0;
		migrate->cpages++;
		ret = set_pmd_migration_entry(&pvmw, folio_page(folio, 0));
		if (ret) {
			migrate->npages--;
			migrate->cpages--;
			migrate->src[migrate->npages] = 0;
			migrate->dst[migrate->npages] = 0;
			goto fallback;
		}
		migrate_vma_collect_skip(start + PAGE_SIZE, end, walk);
		spin_unlock(ptl);
		return 0;
	}

fallback:
	spin_unlock(ptl);
	if (!folio_test_large(folio))
		goto done;
	ret = split_folio(folio);
	if (fault_folio != folio)
		folio_unlock(folio);
	folio_put(folio);
	if (ret)
		return migrate_vma_collect_skip(start, end, walk);
	if (pmd_none(pmdp_get_lockless(pmdp)))
		return migrate_vma_collect_hole(start, end, -1, walk);

done:
	return -ENOENT;
}

static int migrate_vma_collect_pmd(pmd_t *pmdp,
				   unsigned long start,
				   unsigned long end,
				   struct mm_walk *walk)
{
	struct migrate_vma *migrate = walk->private;
	struct vm_area_struct *vma = walk->vma;
	struct mm_struct *mm = vma->vm_mm;
	unsigned long addr = start, unmapped = 0;
	spinlock_t *ptl;
	struct folio *fault_folio = migrate->fault_page ?
		page_folio(migrate->fault_page) : NULL;
	pte_t *ptep;

again:
	if (pmd_trans_huge(*pmdp) || !pmd_present(*pmdp)) {
		int ret = migrate_vma_collect_huge_pmd(pmdp, start, end, walk, fault_folio);

		if (ret == -EAGAIN)
			goto again;
		if (ret == 0)
			return 0;
	}

	ptep = pte_offset_map_lock(mm, pmdp, start, &ptl);
	if (!ptep)
		goto again;
	lazy_mmu_mode_enable();
	ptep += (addr - start) / PAGE_SIZE;

	for (; addr < end; addr += PAGE_SIZE, ptep++) {
		struct dev_pagemap *pgmap;
		unsigned long mpfn = 0, pfn;
		struct folio *folio;
		struct page *page;
		softleaf_t entry;
		pte_t pte;

		pte = ptep_get(ptep);

		if (pte_none(pte)) {
			if (vma_is_anonymous(vma)) {
				mpfn = MIGRATE_PFN_MIGRATE;
				migrate->cpages++;
			}
			goto next;
		}

		if (!pte_present(pte)) {
			/*
			 * Only care about unaddressable device page special
			 * page table entry. Other special swap entries are not
			 * migratable, and we ignore regular swapped page.
			 */
			entry = softleaf_from_pte(pte);
			if (!softleaf_is_device_private(entry))
				goto next;

			page = softleaf_to_page(entry);
			pgmap = page_pgmap(page);
			if (!(migrate->flags &
				MIGRATE_VMA_SELECT_DEVICE_PRIVATE) ||
			    pgmap->owner != migrate->pgmap_owner)
				goto next;

			folio = page_folio(page);
			if (folio_test_large(folio)) {
				int ret;

				lazy_mmu_mode_disable();
				pte_unmap_unlock(ptep, ptl);
				ret = migrate_vma_split_folio(folio,
							  migrate->fault_page);

				if (ret) {
					if (unmapped)
						flush_tlb_range(walk->vma, start, end);

					return migrate_vma_collect_skip(addr, end, walk);
				}

				goto again;
			}

			mpfn = migrate_pfn(page_to_pfn(page)) |
					MIGRATE_PFN_MIGRATE;
			if (softleaf_is_device_private_write(entry))
				mpfn |= MIGRATE_PFN_WRITE;
		} else {
			pfn = pte_pfn(pte);
			if (is_zero_pfn(pfn) &&
			    (migrate->flags & MIGRATE_VMA_SELECT_SYSTEM)) {
				mpfn = MIGRATE_PFN_MIGRATE;
				migrate->cpages++;
				goto next;
			}
			page = vm_normal_page(migrate->vma, addr, pte);
			if (page && !is_zone_device_page(page) &&
			    !(migrate->flags & MIGRATE_VMA_SELECT_SYSTEM)) {
				goto next;
			} else if (page && is_device_coherent_page(page)) {
				pgmap = page_pgmap(page);

				if (!(migrate->flags &
					MIGRATE_VMA_SELECT_DEVICE_COHERENT) ||
					pgmap->owner != migrate->pgmap_owner)
					goto next;
			}
			folio = page ? page_folio(page) : NULL;
			if (folio && folio_test_large(folio)) {
				int ret;

				lazy_mmu_mode_disable();
				pte_unmap_unlock(ptep, ptl);
				ret = migrate_vma_split_folio(folio,
							  migrate->fault_page);

				if (ret) {
					if (unmapped)
						flush_tlb_range(walk->vma, start, end);

					return migrate_vma_collect_skip(addr, end, walk);
				}

				goto again;
			}
			mpfn = migrate_pfn(pfn) | MIGRATE_PFN_MIGRATE;
			mpfn |= pte_write(pte) ? MIGRATE_PFN_WRITE : 0;
		}

		if (!page || !page->mapping) {
			mpfn = 0;
			goto next;
		}

		/*
		 * By getting a reference on the folio we pin it and that blocks
		 * any kind of migration. Side effect is that it "freezes" the
		 * pte.
		 *
		 * We drop this reference after isolating the folio from the lru
		 * for non device folio (device folio are not on the lru and thus
		 * can't be dropped from it).
		 */
		folio = page_folio(page);
		folio_get(folio);

		/*
		 * We rely on folio_trylock() to avoid deadlock between
		 * concurrent migrations where each is waiting on the others
		 * folio lock. If we can't immediately lock the folio we fail this
		 * migration as it is only best effort anyway.
		 *
		 * If we can lock the folio it's safe to set up a migration entry
		 * now. In the common case where the folio is mapped once in a
		 * single process setting up the migration entry now is an
		 * optimisation to avoid walking the rmap later with
		 * try_to_migrate().
		 */
		if (fault_folio == folio || folio_trylock(folio)) {
			bool anon_exclusive;
			pte_t swp_pte;

			if (pte_present(pte))
				flush_cache_page(vma, addr, pte_pfn(pte));
			anon_exclusive = folio_test_anon(folio) &&
					  PageAnonExclusive(page);
			if (anon_exclusive) {
				pte = ptep_clear_flush(vma, addr, ptep);

				if (folio_try_share_anon_rmap_pte(folio, page)) {
					set_pte_at(mm, addr, ptep, pte);
					if (fault_folio != folio)
						folio_unlock(folio);
					folio_put(folio);
					mpfn = 0;
					goto next;
				}
			} else {
				pte = ptep_get_and_clear(mm, addr, ptep);
			}

			migrate->cpages++;

			/* Set the dirty flag on the folio now the pte is gone. */
			if (pte_present(pte) && pte_dirty(pte))
				folio_mark_dirty(folio);

			/* Setup special migration page table entry */
			if (mpfn & MIGRATE_PFN_WRITE)
				entry = make_writable_migration_entry(
							page_to_pfn(page));
			else if (anon_exclusive)
				entry = make_readable_exclusive_migration_entry(
							page_to_pfn(page));
			else
				entry = make_readable_migration_entry(
							page_to_pfn(page));
			if (pte_present(pte)) {
				if (pte_young(pte))
					entry = make_migration_entry_young(entry);
				if (pte_dirty(pte))
					entry = make_migration_entry_dirty(entry);
			}
			swp_pte = swp_entry_to_pte(entry);
			if (pte_present(pte)) {
				if (pte_soft_dirty(pte))
					swp_pte = pte_swp_mksoft_dirty(swp_pte);
				if (pte_uffd_wp(pte))
					swp_pte = pte_swp_mkuffd_wp(swp_pte);
			} else {
				if (pte_swp_soft_dirty(pte))
					swp_pte = pte_swp_mksoft_dirty(swp_pte);
				if (pte_swp_uffd_wp(pte))
					swp_pte = pte_swp_mkuffd_wp(swp_pte);
			}
			set_pte_at(mm, addr, ptep, swp_pte);

			/*
			 * This is like regular unmap: we remove the rmap and
			 * drop the folio refcount. The folio won't be freed, as
			 * we took a reference just above.
			 */
			folio_remove_rmap_pte(folio, page, vma);
			folio_put(folio);

			if (pte_present(pte))
				unmapped++;
		} else {
			folio_put(folio);
			mpfn = 0;
		}

next:
		migrate->dst[migrate->npages] = 0;
		migrate->src[migrate->npages++] = mpfn;
	}

	/* Only flush the TLB if we actually modified any entries */
	if (unmapped)
		flush_tlb_range(walk->vma, start, end);

	lazy_mmu_mode_disable();
	pte_unmap_unlock(ptep - 1, ptl);

	return 0;
}

static const struct mm_walk_ops migrate_vma_walk_ops = {
	.pmd_entry		= migrate_vma_collect_pmd,
	.pte_hole		= migrate_vma_collect_hole,
	.walk_lock		= PGWALK_RDLOCK,
};

/*
 * migrate_vma_collect() - collect pages over a range of virtual addresses
 * @migrate: migrate struct containing all migration information
 *
 * This will walk the CPU page table. For each virtual address backed by a
 * valid page, it updates the src array and takes a reference on the page, in
 * order to pin the page until we lock it and unmap it.
 */
static void migrate_vma_collect(struct migrate_vma *migrate)
{
	struct mmu_notifier_range range;

	/*
	 * Note that the pgmap_owner is passed to the mmu notifier callback so
	 * that the registered device driver can skip invalidating device
	 * private page mappings that won't be migrated.
	 */
	mmu_notifier_range_init_owner(&range, MMU_NOTIFY_MIGRATE, 0,
		migrate->vma->vm_mm, migrate->start, migrate->end,
		migrate->pgmap_owner);
	mmu_notifier_invalidate_range_start(&range);

	walk_page_range(migrate->vma->vm_mm, migrate->start, migrate->end,
			&migrate_vma_walk_ops, migrate);

	mmu_notifier_invalidate_range_end(&range);
	migrate->end = migrate->start + (migrate->npages << PAGE_SHIFT);
}

/*
 * migrate_vma_check_page() - check if page is pinned or not
 * @page: struct page to check
 *
 * Pinned pages cannot be migrated. This is the same test as in
 * folio_migrate_mapping(), except that here we allow migration of a
 * ZONE_DEVICE page.
 */
static bool migrate_vma_check_page(struct page *page, struct page *fault_page)
{
	struct folio *folio = page_folio(page);

	/*
	 * One extra ref because caller holds an extra reference, either from
	 * folio_isolate_lru() for a regular folio, or migrate_vma_collect() for
	 * a device folio.
	 */
	int extra = 1 + (page == fault_page);

	/* Page from ZONE_DEVICE have one extra reference */
	if (folio_is_zone_device(folio))
		extra++;

	/* For file back page */
	if (folio_mapping(folio))
		extra += 1 + folio_has_private(folio);

	if ((folio_ref_count(folio) - extra) > folio_mapcount(folio))
		return false;

	return true;
}

/*
 * Unmaps pages for migration. Returns number of source pfns marked as
 * migrating.
 */
static unsigned long migrate_device_unmap(unsigned long *src_pfns,
					  unsigned long npages,
					  struct page *fault_page)
{
	struct folio *fault_folio = fault_page ?
		page_folio(fault_page) : NULL;
	unsigned long i, restore = 0;
	bool allow_drain = true;
	unsigned long unmapped = 0;

	lru_add_drain();

	for (i = 0; i < npages; ) {
		struct page *page = migrate_pfn_to_page(src_pfns[i]);
		struct folio *folio;
		unsigned int nr = 1;

		if (!page) {
			if (src_pfns[i] & MIGRATE_PFN_MIGRATE)
				unmapped++;
			goto next;
		}

		folio =	page_folio(page);
		nr = folio_nr_pages(folio);

		if (nr > 1)
			src_pfns[i] |= MIGRATE_PFN_COMPOUND;


		/* ZONE_DEVICE folios are not on LRU */
		if (!folio_is_zone_device(folio)) {
			if (!folio_test_lru(folio) && allow_drain) {
				/* Drain CPU's lru cache */
				lru_add_drain_all();
				allow_drain = false;
			}

			if (!folio_isolate_lru(folio)) {
				src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
				restore++;
				goto next;
			}

			/* Drop the reference we took in collect */
			folio_put(folio);
		}

		if (folio_mapped(folio))
			try_to_migrate(folio, 0);

		if (folio_mapped(folio) ||
		    !migrate_vma_check_page(page, fault_page)) {
			if (!folio_is_zone_device(folio)) {
				folio_get(folio);
				folio_putback_lru(folio);
			}

			src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
			restore++;
			goto next;
		}

		unmapped++;
next:
		i += nr;
	}

	for (i = 0; i < npages && restore; i++) {
		struct page *page = migrate_pfn_to_page(src_pfns[i]);
		struct folio *folio;

		if (!page || (src_pfns[i] & MIGRATE_PFN_MIGRATE))
			continue;

		folio = page_folio(page);
		remove_migration_ptes(folio, folio, 0);

		src_pfns[i] = 0;
		if (fault_folio != folio)
			folio_unlock(folio);
		folio_put(folio);
		restore--;
	}

	return unmapped;
}

/*
 * migrate_vma_unmap() - replace page mapping with special migration pte entry
 * @migrate: migrate struct containing all migration information
 *
 * Isolate pages from the LRU and replace mappings (CPU page table pte) with a
 * special migration pte entry and check if it has been pinned. Pinned pages are
 * restored because we cannot migrate them.
 *
 * This is the last step before we call the device driver callback to allocate
 * destination memory and copy contents of original page over to new page.
 */
static void migrate_vma_unmap(struct migrate_vma *migrate)
{
	migrate->cpages = migrate_device_unmap(migrate->src, migrate->npages,
					migrate->fault_page);
}

/**
 * migrate_vma_setup() - prepare to migrate a range of memory
 * @args: contains the vma, start, and pfns arrays for the migration
 *
 * Returns: negative errno on failures, 0 when 0 or more pages were migrated
 * without an error.
 *
 * Prepare to migrate a range of memory virtual address range by collecting all
 * the pages backing each virtual address in the range, saving them inside the
 * src array.  Then lock those pages and unmap them. Once the pages are locked
 * and unmapped, check whether each page is pinned or not.  Pages that aren't
 * pinned have the MIGRATE_PFN_MIGRATE flag set (by this function) in the
 * corresponding src array entry.  Then restores any pages that are pinned, by
 * remapping and unlocking those pages.
 *
 * The caller should then allocate destination memory and copy source memory to
 * it for all those entries (ie with MIGRATE_PFN_VALID and MIGRATE_PFN_MIGRATE
 * flag set).  Once these are allocated and copied, the caller must update each
 * corresponding entry in the dst array with the pfn value of the destination
 * page and with MIGRATE_PFN_VALID. Destination pages must be locked via
 * lock_page().
 *
 * Note that the caller does not have to migrate all the pages that are marked
 * with MIGRATE_PFN_MIGRATE flag in src array unless this is a migration from
 * device memory to system memory.  If the caller cannot migrate a device page
 * back to system memory, then it must return VM_FAULT_SIGBUS, which has severe
 * consequences for the userspace process, so it must be avoided if at all
 * possible.
 *
 * For empty entries inside CPU page table (pte_none() or pmd_none() is true) we
 * do set MIGRATE_PFN_MIGRATE flag inside the corresponding source array thus
 * allowing the caller to allocate device memory for those unbacked virtual
 * addresses.  For this the caller simply has to allocate device memory and
 * properly set the destination entry like for regular migration.  Note that
 * this can still fail, and thus inside the device driver you must check if the
 * migration was successful for those entries after calling migrate_vma_pages(),
 * just like for regular migration.
 *
 * After that, the callers must call migrate_vma_pages() to go over each entry
 * in the src array that has the MIGRATE_PFN_VALID and MIGRATE_PFN_MIGRATE flag
 * set. If the corresponding entry in dst array has MIGRATE_PFN_VALID flag set,
 * then migrate_vma_pages() to migrate struct page information from the source
 * struct page to the destination struct page.  If it fails to migrate the
 * struct page information, then it clears the MIGRATE_PFN_MIGRATE flag in the
 * src array.
 *
 * At this point all successfully migrated pages have an entry in the src
 * array with MIGRATE_PFN_VALID and MIGRATE_PFN_MIGRATE flag set and the dst
 * array entry with MIGRATE_PFN_VALID flag set.
 *
 * Once migrate_vma_pages() returns the caller may inspect which pages were
 * successfully migrated, and which were not.  Successfully migrated pages will
 * have the MIGRATE_PFN_MIGRATE flag set for their src array entry.
 *
 * It is safe to update device page table after migrate_vma_pages() because
 * both destination and source page are still locked, and the mmap_lock is held
 * in read mode (hence no one can unmap the range being migrated).
 *
 * Once the caller is done cleaning up things and updating its page table (if it
 * chose to do so, this is not an obligation) it finally calls
 * migrate_vma_finalize() to update the CPU page table to point to new pages
 * for successfully migrated pages or otherwise restore the CPU page table to
 * point to the original source pages.
 */
int migrate_vma_setup(struct migrate_vma *args)
{
	long nr_pages = (args->end - args->start) >> PAGE_SHIFT;

	args->start &= PAGE_MASK;
	args->end &= PAGE_MASK;
	if (!args->vma || is_vm_hugetlb_page(args->vma) ||
	    (args->vma->vm_flags & VM_SPECIAL) || vma_is_dax(args->vma))
		return -EINVAL;
	if (nr_pages <= 0)
		return -EINVAL;
	if (args->start < args->vma->vm_start ||
	    args->start >= args->vma->vm_end)
		return -EINVAL;
	if (args->end <= args->vma->vm_start || args->end > args->vma->vm_end)
		return -EINVAL;
	if (!args->src || !args->dst)
		return -EINVAL;
	if (args->fault_page && !is_device_private_page(args->fault_page))
		return -EINVAL;
	if (args->fault_page && !PageLocked(args->fault_page))
		return -EINVAL;

	memset(args->src, 0, sizeof(*args->src) * nr_pages);
	args->cpages = 0;
	args->npages = 0;

	migrate_vma_collect(args);

	if (args->cpages)
		migrate_vma_unmap(args);

	/*
	 * At this point pages are locked and unmapped, and thus they have
	 * stable content and can safely be copied to destination memory that
	 * is allocated by the drivers.
	 */
	return 0;

}
EXPORT_SYMBOL(migrate_vma_setup);

#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
/**
 * migrate_vma_insert_huge_pmd_page: Insert a huge folio into @migrate->vma->vm_mm
 * at @addr. folio is already allocated as a part of the migration process with
 * large page.
 *
 * @page needs to be initialized and setup after it's allocated. The code bits
 * here follow closely the code in __do_huge_pmd_anonymous_page(). This API does
 * not support THP zero pages.
 *
 * @migrate: migrate_vma arguments
 * @addr: address where the folio will be inserted
 * @page: page to be inserted at @addr
 * @src: src pfn which is being migrated
 * @pmdp: pointer to the pmd
 */
static int migrate_vma_insert_huge_pmd_page(struct migrate_vma *migrate,
					 unsigned long addr,
					 struct page *page,
					 unsigned long *src,
					 pmd_t *pmdp)
{
	struct vm_area_struct *vma = migrate->vma;
	gfp_t gfp = vma_thp_gfp_mask(vma);
	struct folio *folio = page_folio(page);
	int ret;
	vm_fault_t csa_ret;
	spinlock_t *ptl;
	pgtable_t pgtable;
	pmd_t entry;
	bool flush = false;
	unsigned long i;

	VM_WARN_ON_ONCE(!folio);

	if (!thp_vma_suitable_order(vma, addr, HPAGE_PMD_ORDER))
		return -EINVAL;

	ret = anon_vma_prepare(vma);
	if (ret)
		return ret;

	folio_set_order(folio, HPAGE_PMD_ORDER);
	folio_set_large_rmappable(folio);

	if (mem_cgroup_charge(folio, migrate->vma->vm_mm, gfp)) {
		count_vm_event(THP_FAULT_FALLBACK);
		count_mthp_stat(HPAGE_PMD_ORDER, MTHP_STAT_ANON_FAULT_FALLBACK_CHARGE);
		ret = -ENOMEM;
		goto abort;
	}

	__folio_mark_uptodate(folio);

	pgtable = pte_alloc_one(vma->vm_mm);
	if (unlikely(!pgtable))
		goto abort;

	if (folio_is_device_private(folio)) {
		swp_entry_t swp_entry;

		if (vma->vm_flags & VM_WRITE)
			swp_entry = make_writable_device_private_entry(
						page_to_pfn(page));
		else
			swp_entry = make_readable_device_private_entry(
						page_to_pfn(page));
		entry = swp_entry_to_pmd(swp_entry);
	} else {
		if (folio_is_zone_device(folio) &&
		    !folio_is_device_coherent(folio)) {
			goto free_abort;
		}
		entry = folio_mk_pmd(folio, vma->vm_page_prot);
		if (vma->vm_flags & VM_WRITE)
			entry = pmd_mkwrite(pmd_mkdirty(entry), vma);
	}

	ptl = pmd_lock(vma->vm_mm, pmdp);
	csa_ret = check_stable_address_space(vma->vm_mm);
	if (csa_ret)
		goto unlock_abort;

	/*
	 * Check for userfaultfd but do not deliver the fault. Instead,
	 * just back off.
	 */
	if (userfaultfd_missing(vma))
		goto unlock_abort;

	if (is_huge_zero_pmd(*pmdp))
		flush = true;
	else if (!pmd_none(*pmdp))
		goto unlock_abort;

	add_mm_counter(vma->vm_mm, MM_ANONPAGES, HPAGE_PMD_NR);
	folio_add_new_anon_rmap(folio, vma, addr, RMAP_EXCLUSIVE);
	if (!folio_is_zone_device(folio))
		folio_add_lru_vma(folio, vma);
	folio_get(folio);

	if (flush) {
		pte_free(vma->vm_mm, pgtable);
		flush_cache_page(vma, addr, addr + HPAGE_PMD_SIZE);
		pmdp_invalidate(vma, addr, pmdp);
	} else {
		pgtable_trans_huge_deposit(vma->vm_mm, pmdp, pgtable);
		mm_inc_nr_ptes(vma->vm_mm);
	}
	set_pmd_at(vma->vm_mm, addr, pmdp, entry);
	update_mmu_cache_pmd(vma, addr, pmdp);

	spin_unlock(ptl);

	count_vm_event(THP_FAULT_ALLOC);
	count_mthp_stat(HPAGE_PMD_ORDER, MTHP_STAT_ANON_FAULT_ALLOC);
	count_memcg_event_mm(vma->vm_mm, THP_FAULT_ALLOC);

	return 0;

unlock_abort:
	spin_unlock(ptl);
free_abort:
	pte_free(vma->vm_mm, pgtable);
abort:
	for (i = 0; i < HPAGE_PMD_NR; i++)
		src[i] &= ~MIGRATE_PFN_MIGRATE;
	return 0;
}

static int migrate_vma_split_unmapped_folio(struct migrate_vma *migrate,
					    unsigned long idx, unsigned long addr,
					    struct folio *folio)
{
	unsigned long i;
	unsigned long pfn;
	unsigned long flags;
	int ret = 0;

	/*
	 * take a reference, since split_huge_pmd_address() with freeze = true
	 * drops a reference at the end.
	 */
	folio_get(folio);
	split_huge_pmd_address(migrate->vma, addr, true);
	ret = folio_split_unmapped(folio, 0);
	if (ret)
		return ret;
	migrate->src[idx] &= ~MIGRATE_PFN_COMPOUND;
	flags = migrate->src[idx] & ((1UL << MIGRATE_PFN_SHIFT) - 1);
	pfn = migrate->src[idx] >> MIGRATE_PFN_SHIFT;
	for (i = 1; i < HPAGE_PMD_NR; i++)
		migrate->src[i+idx] = migrate_pfn(pfn + i) | flags;
	return ret;
}
#else /* !CONFIG_ARCH_ENABLE_THP_MIGRATION */
static int migrate_vma_insert_huge_pmd_page(struct migrate_vma *migrate,
					 unsigned long addr,
					 struct page *page,
					 unsigned long *src,
					 pmd_t *pmdp)
{
	return 0;
}

static int migrate_vma_split_unmapped_folio(struct migrate_vma *migrate,
					    unsigned long idx, unsigned long addr,
					    struct folio *folio)
{
	return 0;
}
#endif

static unsigned long migrate_vma_nr_pages(unsigned long *src)
{
	unsigned long nr = 1;
#ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION
	if (*src & MIGRATE_PFN_COMPOUND)
		nr = HPAGE_PMD_NR;
#else
	if (*src & MIGRATE_PFN_COMPOUND)
		VM_WARN_ON_ONCE(true);
#endif
	return nr;
}

/*
 * This code closely matches the code in:
 *   __handle_mm_fault()
 *     handle_pte_fault()
 *       do_anonymous_page()
 * to map in an anonymous zero page but the struct page will be a ZONE_DEVICE
 * private or coherent page.
 */
static void migrate_vma_insert_page(struct migrate_vma *migrate,
				    unsigned long addr,
				    unsigned long *dst,
				    unsigned long *src)
{
	struct page *page = migrate_pfn_to_page(*dst);
	struct folio *folio = page_folio(page);
	struct vm_area_struct *vma = migrate->vma;
	struct mm_struct *mm = vma->vm_mm;
	bool flush = false;
	spinlock_t *ptl;
	pte_t entry;
	pgd_t *pgdp;
	p4d_t *p4dp;
	pud_t *pudp;
	pmd_t *pmdp;
	pte_t *ptep;
	pte_t orig_pte;

	/* Only allow populating anonymous memory */
	if (!vma_is_anonymous(vma))
		goto abort;

	pgdp = pgd_offset(mm, addr);
	p4dp = p4d_alloc(mm, pgdp, addr);
	if (!p4dp)
		goto abort;
	pudp = pud_alloc(mm, p4dp, addr);
	if (!pudp)
		goto abort;
	pmdp = pmd_alloc(mm, pudp, addr);
	if (!pmdp)
		goto abort;

	if (thp_migration_supported() && (*dst & MIGRATE_PFN_COMPOUND)) {
		int ret = migrate_vma_insert_huge_pmd_page(migrate, addr, page,
								src, pmdp);
		if (ret)
			goto abort;
		return;
	}

	if (!pmd_none(*pmdp)) {
		if (pmd_trans_huge(*pmdp)) {
			if (!is_huge_zero_pmd(*pmdp))
				goto abort;
			split_huge_pmd(vma, pmdp, addr);
		} else if (pmd_leaf(*pmdp))
			goto abort;
	}

	if (pte_alloc(mm, pmdp))
		goto abort;
	if (unlikely(anon_vma_prepare(vma)))
		goto abort;
	if (mem_cgroup_charge(folio, vma->vm_mm, GFP_KERNEL))
		goto abort;

	/*
	 * The memory barrier inside __folio_mark_uptodate makes sure that
	 * preceding stores to the folio contents become visible before
	 * the set_pte_at() write.
	 */
	__folio_mark_uptodate(folio);

	if (folio_is_device_private(folio)) {
		swp_entry_t swp_entry;

		if (vma->vm_flags & VM_WRITE)
			swp_entry = make_writable_device_private_entry(
						page_to_pfn(page));
		else
			swp_entry = make_readable_device_private_entry(
						page_to_pfn(page));
		entry = swp_entry_to_pte(swp_entry);
	} else {
		if (folio_is_zone_device(folio) &&
		    !folio_is_device_coherent(folio)) {
			pr_warn_once("Unsupported ZONE_DEVICE page type.\n");
			goto abort;
		}
		entry = mk_pte(page, vma->vm_page_prot);
		if (vma->vm_flags & VM_WRITE)
			entry = pte_mkwrite(pte_mkdirty(entry), vma);
	}

	ptep = pte_offset_map_lock(mm, pmdp, addr, &ptl);
	if (!ptep)
		goto abort;
	orig_pte = ptep_get(ptep);

	if (check_stable_address_space(mm))
		goto unlock_abort;

	if (pte_present(orig_pte)) {
		unsigned long pfn = pte_pfn(orig_pte);

		if (!is_zero_pfn(pfn))
			goto unlock_abort;
		flush = true;
	} else if (!pte_none(orig_pte))
		goto unlock_abort;

	/*
	 * Check for userfaultfd but do not deliver the fault. Instead,
	 * just back off.
	 */
	if (userfaultfd_missing(vma))
		goto unlock_abort;

	inc_mm_counter(mm, MM_ANONPAGES);
	folio_add_new_anon_rmap(folio, vma, addr, RMAP_EXCLUSIVE);
	if (!folio_is_zone_device(folio))
		folio_add_lru_vma(folio, vma);
	folio_get(folio);

	if (flush) {
		flush_cache_page(vma, addr, pte_pfn(orig_pte));
		ptep_clear_flush(vma, addr, ptep);
	}
	set_pte_at(mm, addr, ptep, entry);
	update_mmu_cache(vma, addr, ptep);

	pte_unmap_unlock(ptep, ptl);
	*src = MIGRATE_PFN_MIGRATE;
	return;

unlock_abort:
	pte_unmap_unlock(ptep, ptl);
abort:
	*src &= ~MIGRATE_PFN_MIGRATE;
}

static void __migrate_device_pages(unsigned long *src_pfns,
				unsigned long *dst_pfns, unsigned long npages,
				struct migrate_vma *migrate)
{
	struct mmu_notifier_range range;
	unsigned long i, j;
	bool notified = false;
	unsigned long addr;

	for (i = 0; i < npages; ) {
		struct page *newpage = migrate_pfn_to_page(dst_pfns[i]);
		struct page *page = migrate_pfn_to_page(src_pfns[i]);
		struct address_space *mapping;
		struct folio *newfolio, *folio;
		int r, extra_cnt = 0;
		unsigned long nr = 1;

		if (!newpage) {
			src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
			goto next;
		}

		if (!page) {
			unsigned long addr;

			if (!(src_pfns[i] & MIGRATE_PFN_MIGRATE))
				goto next;

			/*
			 * The only time there is no vma is when called from
			 * migrate_device_coherent_folio(). However this isn't
			 * called if the page could not be unmapped.
			 */
			VM_BUG_ON(!migrate);
			addr = migrate->start + i*PAGE_SIZE;
			if (!notified) {
				notified = true;

				mmu_notifier_range_init_owner(&range,
					MMU_NOTIFY_MIGRATE, 0,
					migrate->vma->vm_mm, addr, migrate->end,
					migrate->pgmap_owner);
				mmu_notifier_invalidate_range_start(&range);
			}

			if ((src_pfns[i] & MIGRATE_PFN_COMPOUND) &&
				(!(dst_pfns[i] & MIGRATE_PFN_COMPOUND))) {
				nr = migrate_vma_nr_pages(&src_pfns[i]);
				src_pfns[i] &= ~MIGRATE_PFN_COMPOUND;
			} else {
				nr = 1;
			}

			for (j = 0; j < nr && i + j < npages; j++) {
				src_pfns[i+j] |= MIGRATE_PFN_MIGRATE;
				migrate_vma_insert_page(migrate,
					addr + j * PAGE_SIZE,
					&dst_pfns[i+j], &src_pfns[i+j]);
			}
			goto next;
		}

		newfolio = page_folio(newpage);
		folio = page_folio(page);
		mapping = folio_mapping(folio);

		/*
		 * If THP migration is enabled, check if both src and dst
		 * can migrate large pages
		 */
		if (thp_migration_supported()) {
			if ((src_pfns[i] & MIGRATE_PFN_MIGRATE) &&
				(src_pfns[i] & MIGRATE_PFN_COMPOUND) &&
				!(dst_pfns[i] & MIGRATE_PFN_COMPOUND)) {

				if (!migrate) {
					src_pfns[i] &= ~(MIGRATE_PFN_MIGRATE |
							 MIGRATE_PFN_COMPOUND);
					goto next;
				}
				nr = 1 << folio_order(folio);
				addr = migrate->start + i * PAGE_SIZE;
				if (migrate_vma_split_unmapped_folio(migrate, i, addr, folio)) {
					src_pfns[i] &= ~(MIGRATE_PFN_MIGRATE |
							 MIGRATE_PFN_COMPOUND);
					goto next;
				}

				/*
				 * reset nr so that only first after-split folio
				 * is processed below
				 */
				VM_WARN_ON_ONCE(folio_test_large(folio));
				nr = 1;
			} else if ((src_pfns[i] & MIGRATE_PFN_MIGRATE) &&
				(dst_pfns[i] & MIGRATE_PFN_COMPOUND) &&
				!(src_pfns[i] & MIGRATE_PFN_COMPOUND)) {
				src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
			}
		}


		if (folio_is_device_private(newfolio) ||
		    folio_is_device_coherent(newfolio)) {
			if (mapping) {
				/*
				 * For now only support anonymous memory migrating to
				 * device private or coherent memory.
				 *
				 * Try to get rid of swap cache if possible.
				 */
				if (!folio_test_anon(folio) ||
				    !folio_free_swap(folio)) {
					src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
					goto next;
				}
			}
		} else if (folio_is_zone_device(newfolio)) {
			/*
			 * Other types of ZONE_DEVICE page are not supported.
			 */
			src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
			goto next;
		}

		BUG_ON(folio_test_writeback(folio));

		if (migrate && migrate->fault_page == page)
			extra_cnt = 1;
		for (j = 0; j < nr && i + j < npages; j++) {
			folio = page_folio(migrate_pfn_to_page(src_pfns[i+j]));
			newfolio = page_folio(migrate_pfn_to_page(dst_pfns[i+j]));

			/*
			 * folio_free_swap() removed the folio from the swap
			 * cache. Refresh the saved mapping before migration.
			 */
			mapping = folio_mapping(folio);

			r = folio_migrate_mapping(mapping, newfolio, folio, extra_cnt);
			if (r)
				src_pfns[i+j] &= ~MIGRATE_PFN_MIGRATE;
			else
				folio_migrate_flags(newfolio, folio);
		}
next:
		i += nr;
	}

	if (notified)
		mmu_notifier_invalidate_range_end(&range);
}

/**
 * migrate_device_pages() - migrate meta-data from src page to dst page
 * @src_pfns: src_pfns returned from migrate_device_range()
 * @dst_pfns: array of pfns allocated by the driver to migrate memory to
 * @npages: number of pages in the range
 *
 * Equivalent to migrate_vma_pages(). This is called to migrate struct page
 * meta-data from source struct page to destination.
 */
void migrate_device_pages(unsigned long *src_pfns, unsigned long *dst_pfns,
			unsigned long npages)
{
	__migrate_device_pages(src_pfns, dst_pfns, npages, NULL);
}
EXPORT_SYMBOL(migrate_device_pages);

/**
 * migrate_vma_pages() - migrate meta-data from src page to dst page
 * @migrate: migrate struct containing all migration information
 *
 * This migrates struct page meta-data from source struct page to destination
 * struct page. This effectively finishes the migration from source page to the
 * destination page.
 */
void migrate_vma_pages(struct migrate_vma *migrate)
{
	__migrate_device_pages(migrate->src, migrate->dst, migrate->npages, migrate);
}
EXPORT_SYMBOL(migrate_vma_pages);

static void __migrate_device_finalize(unsigned long *src_pfns,
				      unsigned long *dst_pfns,
				      unsigned long npages,
				      struct page *fault_page)
{
	struct folio *fault_folio = fault_page ?
		page_folio(fault_page) : NULL;
	unsigned long i;

	for (i = 0; i < npages; i++) {
		struct folio *dst = NULL, *src = NULL;
		struct page *newpage = migrate_pfn_to_page(dst_pfns[i]);
		struct page *page = migrate_pfn_to_page(src_pfns[i]);

		if (newpage)
			dst = page_folio(newpage);

		if (!page) {
			if (dst) {
				WARN_ON_ONCE(fault_folio == dst);
				folio_unlock(dst);
				folio_put(dst);
			}
			continue;
		}

		src = page_folio(page);

		if (!(src_pfns[i] & MIGRATE_PFN_MIGRATE) || !dst) {
			if (dst) {
				WARN_ON_ONCE(fault_folio == dst);
				folio_unlock(dst);
				folio_put(dst);
			}
			dst = src;
		}

		if (!folio_is_zone_device(dst))
			folio_add_lru(dst);
		remove_migration_ptes(src, dst, 0);
		if (fault_folio != src)
			folio_unlock(src);
		folio_put(src);

		if (dst != src) {
			WARN_ON_ONCE(fault_folio == dst);
			folio_unlock(dst);
			folio_put(dst);
		}
	}
}

/*
 * migrate_device_finalize() - complete page migration
 * @src_pfns: src_pfns returned from migrate_device_range()
 * @dst_pfns: array of pfns allocated by the driver to migrate memory to
 * @npages: number of pages in the range
 *
 * Completes migration of the page by removing special migration entries.
 * Drivers must ensure copying of page data is complete and visible to the CPU
 * before calling this.
 */
void migrate_device_finalize(unsigned long *src_pfns,
			     unsigned long *dst_pfns, unsigned long npages)
{
	return __migrate_device_finalize(src_pfns, dst_pfns, npages, NULL);
}
EXPORT_SYMBOL(migrate_device_finalize);

/**
 * migrate_vma_finalize() - restore CPU page table entry
 * @migrate: migrate struct containing all migration information
 *
 * This replaces the special migration pte entry with either a mapping to the
 * new page if migration was successful for that page, or to the original page
 * otherwise.
 *
 * This also unlocks the pages and puts them back on the lru, or drops the extra
 * refcount, for device pages.
 */
void migrate_vma_finalize(struct migrate_vma *migrate)
{
	__migrate_device_finalize(migrate->src, migrate->dst, migrate->npages,
				  migrate->fault_page);
}
EXPORT_SYMBOL(migrate_vma_finalize);

static unsigned long migrate_device_pfn_lock(unsigned long pfn)
{
	struct folio *folio;

	folio = folio_get_nontail_page(pfn_to_page(pfn));
	if (!folio)
		return 0;

	if (!folio_trylock(folio)) {
		folio_put(folio);
		return 0;
	}

	return migrate_pfn(pfn) | MIGRATE_PFN_MIGRATE;
}

/**
 * migrate_device_range() - migrate device private pfns to normal memory.
 * @src_pfns: array large enough to hold migrating source device private pfns.
 * @start: starting pfn in the range to migrate.
 * @npages: number of pages to migrate.
 *
 * migrate_vma_setup() is similar in concept to migrate_vma_setup() except that
 * instead of looking up pages based on virtual address mappings a range of
 * device pfns that should be migrated to system memory is used instead.
 *
 * This is useful when a driver needs to free device memory but doesn't know the
 * virtual mappings of every page that may be in device memory. For example this
 * is often the case when a driver is being unloaded or unbound from a device.
 *
 * Like migrate_vma_setup() this function will take a reference and lock any
 * migrating pages that aren't free before unmapping them. Drivers may then
 * allocate destination pages and start copying data from the device to CPU
 * memory before calling migrate_device_pages().
 */
int migrate_device_range(unsigned long *src_pfns, unsigned long start,
			unsigned long npages)
{
	unsigned long i, j, pfn;

	for (pfn = start, i = 0; i < npages; pfn++, i++) {
		struct page *page = pfn_to_page(pfn);
		struct folio *folio = page_folio(page);
		unsigned int nr = 1;

		src_pfns[i] = migrate_device_pfn_lock(pfn);
		nr = folio_nr_pages(folio);
		if (nr > npages - i) {
			if (src_pfns[i] & MIGRATE_PFN_MIGRATE) {
				folio_unlock(folio);
				folio_put(folio);
			}
			memset(&src_pfns[i], 0,
			       (npages - i) * sizeof(*src_pfns));
			break;
		}
		if (nr > 1) {
			src_pfns[i] |= MIGRATE_PFN_COMPOUND;
			for (j = 1; j < nr; j++)
				src_pfns[i+j] = 0;
			i += j - 1;
			pfn += j - 1;
		}
	}

	migrate_device_unmap(src_pfns, npages, NULL);

	return 0;
}
EXPORT_SYMBOL(migrate_device_range);

/**
 * migrate_device_pfns() - migrate device private pfns to normal memory.
 * @src_pfns: pre-populated array of source device private pfns to migrate.
 * @npages: number of pages to migrate.
 *
 * Similar to migrate_device_range() but supports non-contiguous pre-populated
 * array of device pages to migrate.
 */
int migrate_device_pfns(unsigned long *src_pfns, unsigned long npages)
{
	unsigned long i, j;

	for (i = 0; i < npages; i++) {
		struct page *page = pfn_to_page(src_pfns[i]);
		struct folio *folio = page_folio(page);
		unsigned int nr = 1;

		src_pfns[i] = migrate_device_pfn_lock(src_pfns[i]);
		nr = folio_nr_pages(folio);
		if (nr > npages - i) {
			if (src_pfns[i] & MIGRATE_PFN_MIGRATE) {
				folio_unlock(folio);
				folio_put(folio);
			}
			memset(&src_pfns[i], 0,
			       (npages - i) * sizeof(*src_pfns));
			break;
		}
		if (nr > 1) {
			src_pfns[i] |= MIGRATE_PFN_COMPOUND;
			for (j = 1; j < nr; j++)
				src_pfns[i+j] = 0;
			i += j - 1;
		}
	}

	migrate_device_unmap(src_pfns, npages, NULL);

	return 0;
}
EXPORT_SYMBOL(migrate_device_pfns);

/*
 * Migrate a device coherent folio back to normal memory. The caller should have
 * a reference on folio which will be copied to the new folio if migration is
 * successful or dropped on failure.
 */
int migrate_device_coherent_folio(struct folio *folio)
{
	unsigned long src_pfn, dst_pfn = 0;
	struct folio *dfolio;

	WARN_ON_ONCE(folio_test_large(folio));

	folio_lock(folio);
	src_pfn = migrate_pfn(folio_pfn(folio)) | MIGRATE_PFN_MIGRATE;

	/*
	 * We don't have a VMA and don't need to walk the page tables to find
	 * the source folio. So call migrate_vma_unmap() directly to unmap the
	 * folio as migrate_vma_setup() will fail if args.vma == NULL.
	 */
	migrate_device_unmap(&src_pfn, 1, NULL);
	if (!(src_pfn & MIGRATE_PFN_MIGRATE))
		return -EBUSY;

	dfolio = folio_alloc(GFP_USER | __GFP_NOWARN, 0);
	if (dfolio) {
		folio_lock(dfolio);
		dst_pfn = migrate_pfn(folio_pfn(dfolio));
	}

	migrate_device_pages(&src_pfn, &dst_pfn, 1);
	if (src_pfn & MIGRATE_PFN_MIGRATE)
		folio_copy(dfolio, folio);
	migrate_device_finalize(&src_pfn, &dst_pfn, 1);

	if (src_pfn & MIGRATE_PFN_MIGRATE)
		return 0;
	return -EBUSY;
}
