[PATCH 04/13] mm/huge_memory: move softleaf_to_folio() inside migration branch

Usama Arif
2026-04-27T10:06:22Z

change_non_present_huge_pmd() calls softleaf_to_folio() unconditionally
at the top of the function. softleaf_to_folio() extracts a PFN from
the entry and converts it to a folio pointer, which is only meaningful
for migration and device_private entries that encode a real PFN.

A swap entry encodes a swap offset instead, so softleaf_to_folio()
would produce a bogus pointer and crash on mprotect() when a PMD swap
entry is present.

Move the call into the migration_write branch where the folio is
actually used, so the function is safe for any non-present PMD type.

Signed-off-by: Usama Arif <usama.arif@linux.dev>
---
mm/huge_memory.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 49da0746b8ca..d82a19b5e276 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2619,11 +2619,12 @@ static void change_non_present_huge_pmd(struct mm_struct *mm,
bool uffd_wp_resolve)
{
softleaf_t entry = softleaf_from_pmd(*pmd);
- const struct folio *folio = softleaf_to_folio(entry);
pmd_t newpmd;

VM_WARN_ON(!pmd_is_valid_softleaf(*pmd));
if (softleaf_is_migration_write(entry)) {
+ const struct folio *folio = softleaf_to_folio(entry);
+
/*
* A protection check is difficult so
* just be safe and disable write
--
2.52.0