]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blobdiff - mm/hugetlb.c
mm, hugetlb: fix simple resv_huge_pages underflow on UFFDIO_COPY
[mirror_ubuntu-hirsute-kernel.git] / mm / hugetlb.c
index 19c245b96bd116bba6c9c9058b41c1ccf5370d49..4e70f0bce21d34c1c428ec7f228aed18a7c57193 100644 (file)
@@ -4710,10 +4710,20 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm,
        struct page *page;
 
        if (!*pagep) {
-               ret = -ENOMEM;
+               /* If a page already exists, then it's UFFDIO_COPY for
+                * a non-missing case. Return -EEXIST.
+                */
+               if (vm_shared &&
+                   hugetlbfs_pagecache_present(h, dst_vma, dst_addr)) {
+                       ret = -EEXIST;
+                       goto out;
+               }
+
                page = alloc_huge_page(dst_vma, dst_addr, 0);
-               if (IS_ERR(page))
+               if (IS_ERR(page)) {
+                       ret = -ENOMEM;
                        goto out;
+               }
 
                ret = copy_huge_page_from_user(page,
                                                (const void __user *) src_addr,