Userfaultfd minor faults provides userspace with the ability to manually install PTEs with UFFDIO_CONTINUE. Right now, khugepaged collapse can map holes in the VMA when a naturally-aligned THP is present without explicit action from userspace. This is a problem, as it bypasses userfaultfd minor faults that userspace is expecting to handle. If userspace implements post-copy live migration using userfaultfd minor faults, this situation is currently possible: 1. The VMA for guest memory is userfaultfd-minor-registered and nothing is mapped in the page tables. 2. A stale copy of a page is present in a naturally-aligned THP (from pre-copy live migration). 3. khugepaged collapses the mapping of the THP, installs a PMD. 4. The VM now has access to the stale contents => VM is broken. 5. After installing the correct contents, userspace attempts to map the page with UFFDIO_CONTINUE; it gets EEXIST, indicating that something unexpectedly mapped the page. The naturally-aligned THP case is the only case where this is a problem. khugepaged otherwise requires all PTEs to be present for userfaultfd-registered VMAs (i.e., max none PTEs is 0), which is correct. This check is essentially bypassed for naturally-aligned THPs. No changes are needed for file_backed_vma_is_retractable(), as zapping PTEs is safe. Userspace must already handle cases where PTEs are zapped without explicit action (e.g. due to reclaim). Fixes: 58ac9a8993a1 ("mm/khugepaged: attempt to map file/shmem-backed pte-mapped THPs by pmds") Cc: # 6.1 Suggested-by: Lance Yang Tested-by: Lance Yang Signed-off-by: James Houghton --- v1->v2: - Applied Lance's change to move the userfaultfd_minor() check to the right place. - Suggested-by: and Tested-by: Lance. Thank you! - Adjusted the commit description. v1: https://lore.kernel.org/linux-mm/20260828005004.2870750-1-jthoughton@google.com/ --- mm/khugepaged.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mm/khugepaged.c b/mm/khugepaged.c index b237f6e7662a..22356229c1e4 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c @@ -1899,6 +1899,13 @@ static enum scan_result try_collapse_pte_mapped_thp(struct mm_struct *mm, unsign if (userfaultfd_protected(vma)) return SCAN_PTE_UFFD; + /* + * Userfaultfd-minor-registered VMAs should not be collapsed, as + * userspace is expecting to explicitly install PTEs. + */ + if (userfaultfd_minor(vma)) + return SCAN_PTE_UFFD; + folio = filemap_lock_folio(vma->vm_file->f_mapping, linear_page_index(vma, haddr)); if (IS_ERR(folio)) base-commit: 26260251022fbc2f248a3d747a9b2b961b18d2d8 -- 2.55.0.897.gb25b4bd76c-goog