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 481ec7eb44420..a04d62dd1e065 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -1946,7 +1946,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.52.0
