The UFFDIO_MOVE ioctl's move_pages() loop splits a huge PMD when the folio is pinned and can't be moved at PMD granularity.
If the split fails, the PMD stays huge and move_pages_pte() can't process individual pages. Break out of the loop on split failure and return -ENOMEM to the caller. This is similar to how other allocation failures (__pte_alloc, mm_alloc_pmd) are handled in move_pages(). Signed-off-by: Usama Arif <[email protected]> --- mm/userfaultfd.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c index e19872e518785..2728102e00c72 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -1870,7 +1870,13 @@ ssize_t move_pages(struct userfaultfd_ctx *ctx, unsigned long dst_start, } spin_unlock(ptl); - split_huge_pmd(src_vma, src_pmd, src_addr); + /* + * If split fails, the PMD stays huge and + * move_pages_pte can't process it. + */ + err = split_huge_pmd(src_vma, src_pmd, src_addr); + if (err) + break; /* The folio will be split by move_pages_pte() */ continue; } -- 2.47.3
