// 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
 *
 * If @folio is not the folio containing @fault_page, the caller must hold a
 * reference on @folio. The helper consumes that reference.
 *
 * 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_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);

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

		folio = softleaf_to_folio(entry);
		if (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;

				/* migrate_vma_split_folio() consumes this reference */
				if (folio != fault_folio)
					folio_get(folio);
				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;

				/* migrate_vma_split_folio() consumes this reference */
				if (folio != fault_folio)
					folio_get(folio);
				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(pte))
					swp_pte = pte_swp_mkuffd(swp_pte);
			} else {
				if (pte_swp_soft_dirty(pte))
					swp_pte = pte_swp_mksoft_dirty(swp_pte);
				if (pte_swp_uffd(pte))
					swp_pte = pte_swp_mkuffd(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_vma(migrate->vma, 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_HAS_PMD_SOFTLEAVES
/**
 * 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 = softleaf_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_range(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_HAS_PMD_SOFTLEAVES */
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_HAS_PMD_SOFTLEAVES
	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;
}
