[PATCH 01/13] mm: add softleaf_to_pmd() and convert existing callers

From: Usama Arif

Date: Mon Apr 27 2026 - 06:09:34 EST


Add softleaf_to_pmd() as the PMD counterpart to softleaf_to_pte(),
completing the symmetry of the softleaf abstraction for page table
leaf entries.

The upcoming PMD swap entry support needs to construct PMD entries
from swap entries. Converting existing swp_entry_to_pmd() callers
to softleaf_to_pmd() in a prep patch keeps the feature patches
focused on new functionality rather than mixing refactoring with
new code.

Signed-off-by: Usama Arif <usama.arif@xxxxxxxxx>
---
include/linux/leafops.h | 20 ++++++++++++++++++++
mm/huge_memory.c | 12 ++++++------
2 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/include/linux/leafops.h b/include/linux/leafops.h
index 992cd8bd8ed0..803d312437df 100644
--- a/include/linux/leafops.h
+++ b/include/linux/leafops.h
@@ -108,6 +108,21 @@ static inline softleaf_t softleaf_from_pmd(pmd_t pmd)
return swp_entry(__swp_type(arch_entry), __swp_offset(arch_entry));
}

+/**
+ * softleaf_to_pmd() - Obtain a PMD entry from a leaf entry.
+ * @entry: Leaf entry.
+ *
+ * This generates an architecture-specific PMD entry that can be utilised to
+ * encode the metadata the leaf entry encodes.
+ *
+ * Returns: Architecture-specific PMD entry encoding leaf entry.
+ */
+static inline pmd_t softleaf_to_pmd(softleaf_t entry)
+{
+ /* Temporary until swp_entry_t eliminated. */
+ return swp_entry_to_pmd(entry);
+}
+
#else

static inline softleaf_t softleaf_from_pmd(pmd_t pmd)
@@ -115,6 +130,11 @@ static inline softleaf_t softleaf_from_pmd(pmd_t pmd)
return softleaf_mk_none();
}

+static inline pmd_t softleaf_to_pmd(softleaf_t entry)
+{
+ return __pmd(0);
+}
+
#endif

/**
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 970e077019b7..49da0746b8ca 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1881,7 +1881,7 @@ static void copy_huge_non_present_pmd(
if (softleaf_is_migration_write(entry) ||
softleaf_is_migration_read_exclusive(entry)) {
entry = make_readable_migration_entry(swp_offset(entry));
- pmd = swp_entry_to_pmd(entry);
+ pmd = softleaf_to_pmd(entry);
if (pmd_swp_soft_dirty(*src_pmd))
pmd = pmd_swp_mksoft_dirty(pmd);
if (pmd_swp_uffd_wp(*src_pmd))
@@ -1894,7 +1894,7 @@ static void copy_huge_non_present_pmd(
*/
if (softleaf_is_device_private_write(entry)) {
entry = make_readable_device_private_entry(swp_offset(entry));
- pmd = swp_entry_to_pmd(entry);
+ pmd = softleaf_to_pmd(entry);

if (pmd_swp_soft_dirty(*src_pmd))
pmd = pmd_swp_mksoft_dirty(pmd);
@@ -2632,12 +2632,12 @@ static void change_non_present_huge_pmd(struct mm_struct *mm,
entry = make_readable_exclusive_migration_entry(swp_offset(entry));
else
entry = make_readable_migration_entry(swp_offset(entry));
- newpmd = swp_entry_to_pmd(entry);
+ newpmd = softleaf_to_pmd(entry);
if (pmd_swp_soft_dirty(*pmd))
newpmd = pmd_swp_mksoft_dirty(newpmd);
} else if (softleaf_is_device_private_write(entry)) {
entry = make_readable_device_private_entry(swp_offset(entry));
- newpmd = swp_entry_to_pmd(entry);
+ newpmd = softleaf_to_pmd(entry);
} else {
newpmd = *pmd;
}
@@ -5014,7 +5014,7 @@ int set_pmd_migration_entry(struct page_vma_mapped_walk *pvmw,
entry = make_migration_entry_young(entry);
if (pmd_dirty(pmdval))
entry = make_migration_entry_dirty(entry);
- pmdswp = swp_entry_to_pmd(entry);
+ pmdswp = softleaf_to_pmd(entry);
if (pmd_soft_dirty(pmdval))
pmdswp = pmd_swp_mksoft_dirty(pmdswp);
if (pmd_uffd_wp(pmdval))
@@ -5065,7 +5065,7 @@ void remove_migration_pmd(struct page_vma_mapped_walk *pvmw, struct page *new)
else
entry = make_readable_device_private_entry(
page_to_pfn(new));
- pmde = swp_entry_to_pmd(entry);
+ pmde = softleaf_to_pmd(entry);

if (pmd_swp_soft_dirty(*pvmw->pmd))
pmde = pmd_swp_mksoft_dirty(pmde);
--
2.52.0