From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794585508; b=1WNUIfghFjNewd/M/czTlXzoq2yH+D7e2XrA1LU7ohkGrWzGM6o4LBdh5Up0Nki3TUCq bZTD9zwhuSrZD8NJrnXj7xgr12UOEA8Vc7n3ettb/J7f6nW5zTtROp2v3xz0dN5oiOgox waIQGKvmBZ+bQue/ISBipLirsZRkCzzJd1yz63VHlblamh8dyUp3//ARyh8bGW/72EuHg 3Xi+g+Ai19C9bWbrYZY+XfaCpC33nKK3Jc1e05yCQOkkuaIJy/F+xqvxZO9WJ3y5yUaYo FrXtJ9xBJy5rLDumx6uAEmaqQTCOi3V/alW2hE25g/PPlynLDzKuJECFIXv+Gzq6wfw== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794585508; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:User-Agent:X-stable:X-Patchwork-Hint: MIME-Version:Content-Transfer-Encoding; bh=6pbNycz01VFMtmwywpiHfk+CALokh4ilndLm9hJ88B4=; b=v0h8+Uf/MUwYnY7biwtqEIi8rSp0mywdsIX0kh9Xxoygh9MG1b17VMvT9ykrjNwivte0 IY8ZKLwmHXKs7Ss7rx14xeeC28CWCpUCnCGRys+oFSxmuFogPUxr0O5HPWzhmvp9rIPR4 Glz+q1VzzwB0DPK6UikRSWl14WuruYlm5REUjOX4pWqEJBalE0Imc7WVNsTe6YZyp3iWL oONnGzWd6WTdc6xFOzBv6sRbmbVFJJjvGl7WrBotbjPhIsXkb4NSh/AjeRp4jKDxBD+Ze bdNPK8fE7Fp/bw44RwYBrwrtnT+FO/NYnjpjayZsDPY93PpF7OvX2jMLvCxbM711TgQ== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=16dXFPOC; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8476B606AE0B; Fri, 13 Nov 2026 15:58:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=16dXFPOC Received: by smtp.kernel.org (Postfix) with ESMTPSA id 34EA41F000C5; Fri, 13 Nov 2026 15:58:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1794585508; bh=6pbNycz01VFMtmwywpiHfk+CALokh4ilndLm9hJ88B4=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=16dXFPOCxAfAO+UYqWtuNd3egVid2MtjLUjIgV6A1SfGP1yNlUyySHZ7WSq8WJ/v2 zE7zVF7kfwdR762jBposXwkB+YehPfzsQxQfYwhfT/y68D2DQc1KcRm5q2rK2tgWUe 7WAJAhk/2JprENa5B9lDu+H6psKk+47XNvJMH1U8= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Zi Yan , Pedro Falcato , Lance Yang , Muhammad Usama Anjum , "David Hildenbrand (Arm)" , Sasha Levin Subject: [PATCH 7.3 155/507] mm/huge_memory: properly handle refcounted PUD mappings on fork Date: Fri, 13 Nov 2026 10:47:39 -0500 Message-ID: <20261113153759.773075212@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261113153753.358973689@linuxfoundation.org> References: <20261113153753.358973689@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore X-Mailing-List: stable@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 7.3-stable review patch. If anyone has any objections, please let me know. ------------------ From: David Hildenbrand (Arm) [ Upstream commit d90bdc02e36ec08d8248ebc6cdc52e12043eb28c ] copy_huge_pud() copies device-DAX entries without taking a folio reference or updating mapcounts and the child's RSS. For example, MADV_GUARD_INSTALL sets VM_MAYBE_GUARD on a device-DAX VMA, forcing copy_page_range() to traverse the whole VMA on fork. Any remaining huge PUDs are then copied without accounting for the new mappings. Unmapping them in the child decrements accounting that was never added. Use vm_normal_page_pud() to identify refcounted mappings. Take a folio reference and add the child's PUD rmap and RSS accounting before installing the copied entry. Pass src and dst VMAs consistently instead of src and dst MM. Move the TODO. Fixes: aed877c2b4257 ("device/dax: properly refcount device dax pages when mapping") Cc: stable@vger.kernel.org Reviewed-by: Zi Yan Reviewed-by: Pedro Falcato Reviewed-by: Lance Yang Tested-by: Muhammad Usama Anjum Link: https://patch.msgid.link/20261031-fixes_core-v3-11-d6437171ecc3@kernel.org Signed-off-by: David Hildenbrand (Arm) Signed-off-by: Sasha Levin --- include/linux/huge_mm.h | 5 ++--- mm/huge_memory.c | 27 +++++++++++++++++++-------- mm/memory.c | 4 +--- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h index c745f7ad22987..fac05120ab774 100644 --- a/include/linux/huge_mm.h +++ b/include/linux/huge_mm.h @@ -12,9 +12,8 @@ int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm, pmd_t *dst_pmd, pmd_t *src_pmd, unsigned long addr, struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma); bool huge_pmd_set_accessed(struct vm_fault *vmf); -int copy_huge_pud(struct mm_struct *dst_mm, struct mm_struct *src_mm, - pud_t *dst_pud, pud_t *src_pud, unsigned long addr, - struct vm_area_struct *vma); +int copy_huge_pud(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma, + pud_t *dst_pud, pud_t *src_pud, unsigned long addr); #ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD void huge_pud_set_accessed(struct vm_fault *vmf, pud_t orig_pud); diff --git a/mm/huge_memory.c b/mm/huge_memory.c index fd32f629400a6..f5e871059ba6b 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -2073,11 +2073,13 @@ void touch_pud(struct vm_area_struct *vma, unsigned long addr, update_mmu_cache_pud(vma, addr, pud); } -int copy_huge_pud(struct mm_struct *dst_mm, struct mm_struct *src_mm, - pud_t *dst_pud, pud_t *src_pud, unsigned long addr, - struct vm_area_struct *vma) +int copy_huge_pud(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma, + pud_t *dst_pud, pud_t *src_pud, unsigned long addr) { + struct mm_struct *dst_mm = dst_vma->vm_mm; + struct mm_struct *src_mm = src_vma->vm_mm; spinlock_t *dst_ptl, *src_ptl; + struct page *page; pud_t pud; int ret; @@ -2090,11 +2092,20 @@ int copy_huge_pud(struct mm_struct *dst_mm, struct mm_struct *src_mm, if (unlikely(!pud_trans_huge(pud))) goto out_unlock; - /* - * TODO: once we support anonymous pages, use - * folio_try_dup_anon_rmap_*() and split if duplicating fails. - */ - if (vma_is_cow_mapping(vma) && pud_write(pud)) { + page = vm_normal_page_pud(src_vma, addr, pud); + if (page) { + struct folio *folio = page_folio(page); + + folio_get(folio); + /* + * TODO: once we support anonymous pages, use + * folio_try_dup_anon_rmap_*() and split if duplicating fails. + */ + folio_add_file_rmap_pud(folio, page, dst_vma); + add_mm_counter(dst_mm, mm_counter_file(folio), HPAGE_PUD_NR); + } + + if (vma_is_cow_mapping(src_vma) && pud_write(pud)) { pudp_set_wrprotect(src_mm, addr, src_pud); pud = pud_wrprotect(pud); } diff --git a/mm/memory.c b/mm/memory.c index 9e395ad33ffdf..9eb7975e4a45e 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1500,7 +1500,6 @@ copy_pud_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma, unsigned long end) { struct mm_struct *dst_mm = dst_vma->vm_mm; - struct mm_struct *src_mm = src_vma->vm_mm; pud_t *src_pud, *dst_pud; unsigned long next; @@ -1514,8 +1513,7 @@ copy_pud_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma, int err; VM_BUG_ON_VMA(next-addr != HPAGE_PUD_SIZE, src_vma); - err = copy_huge_pud(dst_mm, src_mm, - dst_pud, src_pud, addr, src_vma); + err = copy_huge_pud(dst_vma, src_vma, dst_pud, src_pud, addr); if (err == -ENOMEM) return -ENOMEM; if (!err) -- 2.53.0