[RFC PATCH 2/6] mm/migrate_device: Add migrate PFN flag to track device private PFNs

Jordan Niethe
2025-11-28T04:42:41Z

A future change will remove device private pages from the physical
address space. This will mean that device private pages no longer have
normal PFN and must be handled separately.

Prepare for this by adding a MIGRATE_PFN_DEVICE flag to indicate
that a migrate pfn contains a PFN for a device private page.

Signed-off-by: Jordan Niethe <jniethe@nvidia.com>
Signed-off-by: Alistair Popple <apopple@nvidia.com>

---

Note: Existing drivers must also be updated in next revision.
---
include/linux/migrate.h | 1 +
lib/test_hmm.c | 3 ++-
mm/migrate_device.c | 5 +++--
3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index 1f0ac122c3bf..d8f520dca342 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -125,6 +125,7 @@ static inline int migrate_misplaced_folio(struct folio *folio, int node)
#define MIGRATE_PFN_VALID (1UL << 0)
#define MIGRATE_PFN_MIGRATE (1UL << 1)
#define MIGRATE_PFN_WRITE (1UL << 3)
+#define MIGRATE_PFN_DEVICE (1UL << 4)
#define MIGRATE_PFN_SHIFT 6

static inline struct page *migrate_pfn_to_page(unsigned long mpfn)
diff --git a/lib/test_hmm.c b/lib/test_hmm.c
index 83e3d8208a54..0035e1b7beec 100644
--- a/lib/test_hmm.c
+++ b/lib/test_hmm.c
@@ -684,7 +684,8 @@ static void dmirror_migrate_alloc_and_copy(struct migrate_vma *args,

pr_debug("migrating from sys to dev pfn src: 0x%lx pfn dst: 0x%lx\n",
page_to_pfn(spage), page_to_pfn(dpage));
- *dst = migrate_pfn(page_to_pfn(dpage));
+ *dst = migrate_pfn(page_to_pfn(dpage)) |
+ MIGRATE_PFN_DEVICE;
if ((*src & MIGRATE_PFN_WRITE) ||
(!spage && args->vma->vm_flags & VM_WRITE))
*dst |= MIGRATE_PFN_WRITE;
diff --git a/mm/migrate_device.c b/mm/migrate_device.c
index abd9f6850db6..82f09b24d913 100644
--- a/mm/migrate_device.c
+++ b/mm/migrate_device.c
@@ -148,7 +148,8 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
goto next;

mpfn = migrate_pfn(page_to_pfn(page)) |
- MIGRATE_PFN_MIGRATE;
+ MIGRATE_PFN_MIGRATE |
+ MIGRATE_PFN_DEVICE;
if (is_writable_device_private_entry(entry))
mpfn |= MIGRATE_PFN_WRITE;
} else {
@@ -918,7 +919,7 @@ static unsigned long migrate_device_pfn_lock(unsigned long pfn)
return 0;
}

- return migrate_pfn(pfn) | MIGRATE_PFN_MIGRATE;
+ return migrate_pfn(pfn) | MIGRATE_PFN_MIGRATE | MIGRATE_PFN_DEVICE;
}

/**
--
2.34.1