userfaultfd: wait on source PMD during UFFDIO_MOVE
Subsystems (2)
Usama Arif
reviewerPATCH 1/1 userfaultfd: wait on source PMD during UFFDIO_MOVE
move_pages_huge_pmd() snapshots src_pmdval under src_ptl, drops the lock, and, for migration entries, waits with pmd_migration_entry_wait().
Passing &src_pmdval is wrong. pmd_migration_entry_wait() must lock and re-read the real page-table PMD; on split-PMD-lock kernels, a stack address also resolves to the wrong lock. softleaf_entry_wait_on_locked() then waits without a folio reference, which is safe only while serialized against migration-entry removal by the real PT lock.
Pass src_pmd, matching __handle_mm_fault() and hmm_vma_walk_pmd().
--- mm/huge_memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/huge_memory.c +1 -1
@@ -2775,7 +2775,7 @@ int move_pages_huge_pmd(struct mm_struct *mm, pmd_t *dst_pmd, pmd_t *src_pmd, pmif (!pmd_trans_huge (src_pmdval)) {spin_unlock (src_ptl);if (pmd_is_migration_entry (src_pmdval)) { -pmd_migration_entry_wait (mm, &src_pmdval); +pmd_migration_entry_wait (mm, src_pmd);return -EAGAIN ; }return -ENOENT ;
Signature · 1 line
2.53.0-Meta
Quoted 13 lines · Usama Arif
move_pages_huge_pmd()snapshotssrc_pmdvalundersrc_ptl, drops the lock,
and, for migration entries, waits withpmd_migration_entry_wait().Passing
&src_pmdvalis wrong.pmd_migration_entry_wait()must lock and
re-read the real page-table PMD; on split-PMD-lock kernels, a stack address also resolves to the wrong lock.softleaf_entry_wait_on_locked()
then waits without a folio reference, which is safe only while serialized
against migration-entry removal by the real PT lock.
Quoted 7 lines
Pass
src_pmd, matching__handle_mm_fault()andhmm_vma_walk_pmd().Reported-by sashiko-bot <[email protected]>Link:
https://sashiko.dev/#/patchset/20260703173903.3789516-1-usama.arif%40linux.dev?part=8Fixes adef440691ba ("userfaultfd: UFFDIO_MOVE uABI")Signed-off-by Usama Arif <[email protected]>
Signature · 1 line
All Rights Reversed.
Andrew Morton
maintainerQuoted 10 lines · On Sun, 5 Jul 2026 06:12:31 -0700 Usama Arif <[email protected]> wrote:
move_pages_huge_pmd()snapshotssrc_pmdvalundersrc_ptl, drops the lock, and, for migration entries, waits withpmd_migration_entry_wait().Passing
&src_pmdvalis wrong.pmd_migration_entry_wait()must lock and re-read the real page-table PMD; on split-PMD-lock kernels, a stack address also resolves to the wrong lock.softleaf_entry_wait_on_locked()then waits without a folio reference, which is safe only while serialized against migration-entry removal by the real PT lock.Pass
src_pmd, matching__handle_mm_fault()andhmm_vma_walk_pmd().
Thanks.
Quoted 2 lines
Sashiko says "wild spinlock acquisition and memory corruption", so I'll add a cc:stable to this.
Quoted 11 lines
mm/huge_memory.c +1
-1@@ -2775,7 +2775,7 @@ int move_pages_huge_pmd(struct mm_struct *mm, pmd_t *dst_pmd, pmd_t *src_pmd, pmif (!pmd_trans_huge (src_pmdval)) {spin_unlock (src_ptl);if (pmd_is_migration_entry (src_pmdval)) { -pmd_migration_entry_wait (mm, &src_pmdval); +pmd_migration_entry_wait (mm, src_pmd);return -EAGAIN ; }return -ENOENT ;
Quoted 9 lines · Usama Arif
move_pages_huge_pmd()snapshotssrc_pmdvalundersrc_ptl, drops the lock, and, for migration entries, waits withpmd_migration_entry_wait().Passing
&src_pmdvalis wrong.pmd_migration_entry_wait()must lock and re-read the real page-table PMD; on split-PMD-lock kernels, a stack address also resolves to the wrong lock.softleaf_entry_wait_on_locked()then waits without a folio reference, which is safe only while serialized against migration-entry removal by the real PT lock.
Quoted 7 lines
Pass
src_pmd, matching__handle_mm_fault()andhmm_vma_walk_pmd().Reported-by sashiko-bot <[email protected]>Fixes adef440691ba ("userfaultfd: UFFDIO_MOVE uABI")Signed-off-by Usama Arif <[email protected]>---
Good catch. Agree with Andrew that we should cc stable.
Quoted 6 lines · Usama Arif
move_pages_huge_pmd()snapshotssrc_pmdvalundersrc_ptl, drops the lock, and, for migration entries, waits withpmd_migration_entry_wait().Passing
&src_pmdvalis wrong.pmd_migration_entry_wait()must lock and re-read the real page-table PMD; on split-PMD-lock kernels, a stack address also resolves to the wrong lock.softleaf_entry_wait_on_locked()
Well spotted!
Quoted 10 lines
then waits without a folio reference, which is safe only while serialized against migration-entry removal by the real PT lock.
Pass
src_pmd, matching__handle_mm_fault()andhmm_vma_walk_pmd().Reported-by sashiko-bot <[email protected]>Fixes adef440691ba ("userfaultfd: UFFDIO_MOVE uABI")Signed-off-by Usama Arif <[email protected]>---
As Andrew and Baolin pointed out, this should go to stable ;)
With that,
Quoted 24 lines · Usama Arif
move_pages_huge_pmd()snapshotssrc_pmdvalundersrc_ptl, drops the lock, and, for migration entries, waits withpmd_migration_entry_wait().Passing
&src_pmdvalis wrong.pmd_migration_entry_wait()must lock and re-read the real page-table PMD; on split-PMD-lock kernels, a stack address also resolves to the wrong lock.softleaf_entry_wait_on_locked()then waits without a folio reference, which is safe only while serialized against migration-entry removal by the real PT lock.Pass
src_pmd, matching__handle_mm_fault()andhmm_vma_walk_pmd().Reported-by sashiko-bot <[email protected]>Fixes adef440691ba ("userfaultfd: UFFDIO_MOVE uABI")Signed-off-by Usama Arif <[email protected]>--- mm/huge_memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)mm/huge_memory.c +0
-0
mm/huge_memory.c int move_pages_huge_pmd(struct mm_struct *mm, pmd_t *dst_pmd, pmd_t *src_pmd, pm · line 2781
Quoted 8 lines
mm/huge_memory.c +1
-1@@ -2775,7 +2775,7 @@ int move_pages_huge_pmd(struct mm_struct *mm, pmd_t *dst_pmd, pmd_t *src_pmd, pmif (!pmd_trans_huge (src_pmdval)) {spin_unlock (src_ptl);if (pmd_is_migration_entry (src_pmdval)) { -pmd_migration_entry_wait (mm, &src_pmdval); +pmd_migration_entry_wait (mm, src_pmd);return -EAGAIN ; }return -ENOENT ;
Looks good and follows roughly what we do in __handle_mm_fault().
Signature · 3 lines
Cheers, David
Quoted 8 lines · Usama Arif
move_pages_huge_pmd()snapshotssrc_pmdvalundersrc_ptl, drops the lock, and, for migration entries, waits withpmd_migration_entry_wait().Passing
&src_pmdvalis wrong.pmd_migration_entry_wait()must lock and re-read the real page-table PMD; on split-PMD-lock kernels, a stack address also resolves to the wrong lock.softleaf_entry_wait_on_locked()then waits without a folio reference, which is safe only while serialized against migration-entry removal by the real PT lock.
Yikes!
Quoted 7 lines
Pass
src_pmd, matching__handle_mm_fault()andhmm_vma_walk_pmd().Reported-by sashiko-bot <[email protected]>Fixes adef440691ba ("userfaultfd: UFFDIO_MOVE uABI")Signed-off-by Usama Arif <[email protected]>
LGTM so:
Quoted 18 lines
--- mm/huge_memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)mm/huge_memory.c +1
-2@@ -2775,7 +2775,7 @@ int move_pages_huge_pmd(struct mm_struct *mm, pmd_t *dst_pmd, pmd_t *src_pmd, pmif (!pmd_trans_huge (src_pmdval)) {spin_unlock (src_ptl);if (pmd_is_migration_entry (src_pmdval)) { -pmd_migration_entry_wait (mm, &src_pmdval); +pmd_migration_entry_wait (mm, src_pmd);return -EAGAIN ; }return -ENOENT ; --
Quoted 2 lines
2.53.0-Meta
Cheers, Lorenzo