From: Kiryl Shutsemau (Meta) Date: Fri, 29 May 2026 17:23:28 +0000 (+0100) Subject: mm/huge_memory: preserve pmd_swp_uffd_wp on device-private PMD downgrade X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f7e2c21bd1f57cd5350eecdfdb5d6025ca6afbab;p=thirdparty%2Fkernel%2Fstable.git mm/huge_memory: preserve pmd_swp_uffd_wp on device-private PMD downgrade change_non_present_huge_pmd() rewrites a writable device-private PMD swap entry into a readable one without carrying pmd_swp_uffd_wp() across. The PTE-level change_softleaf_pte() does this correctly; mirror that here, matching what copy_huge_pmd() does for the fork path. Without the carry, a plain mprotect() over a UFFD_WP-marked device-private THP strips the bit and the trap is bypassed on swap-in. Link: https://lore.kernel.org/20260529172331.356655-5-kas@kernel.org Fixes: 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations") Signed-off-by: Kiryl Shutsemau Reported-by: Sashiko AI review Reviewed-by: Balbir Singh Cc: David Hildenbrand Cc: Lorenzo Stoakes Cc: Michal Hocko Cc: Mike Rapoport Cc: Peter Xu Cc: Suren Baghdasaryan Cc: Vlastimil Babka Cc: Signed-off-by: Andrew Morton --- diff --git a/mm/huge_memory.c b/mm/huge_memory.c index da851a5696d5..a5176653ba1f 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2565,6 +2565,8 @@ static void change_non_present_huge_pmd(struct mm_struct *mm, } else if (softleaf_is_device_private_write(entry)) { entry = make_readable_device_private_entry(swp_offset(entry)); newpmd = swp_entry_to_pmd(entry); + if (pmd_swp_uffd_wp(*pmd)) + newpmd = pmd_swp_mkuffd_wp(newpmd); } else { newpmd = *pmd; }