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=1794063756; b=DL17iDX5fuFO6ZqvRgKSrF++II9aQi0qby44qOCGyJh6v6wOrcyP4IlS00yb8NH1uuvL dlcCBxdSWvewkUlt1bG3n9GpLie87zyOo89pBeZAOC3XYsbEqeaXOmI0RmVnbtedgmXBy YtHZ75OeU5t+8g/mdaeGkZmhdcgaJz62P35EQyavREMqoLnoFUNZL+7bxn4KtE5YzAIkd LxIueGpJ/JOr3fAiRIJposGaZPfCPahBXs45BMoJO3uq7JtAqfaSkVym7xRifkuR9VcHm nEPyUfLwyM4/t3ZaGJcU7Dr7nKvLgnrdr4soGE5Bd7Hed7LzjKg+QSITCxn74g9BEiA== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794063756; 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=B9+LbpOXpCowFeJY6JPWOWJvaSEnuV52DkSgT0FGH0g=; b=wGEsIEgJle2ZJj/YI1dC84PXDMYEzmpwtq9vuuCOAVAluG4y2amnRGKvgljRbw88dOAE 34VBUzwAY+QAVc7pyxnyb3Awhnv2kP+mGhS9UEPs8mzUU3A4dZvoNCryH/WHmPiLl5+bL h+X1S+79itZmQkE1uBCwNr6r68OE8XaJaDtpCGYmJRL6ZkOAvDcTmHNHqvPMw1gl2LYRL 1lv1MsSU76uujEKSYypdKTjYMwV1Z6VV3dTPZcAlGQ09RRV8CadKvZ7fDqGwrCjwsMVVw 3o8c0736n3V+wzHZDNs3+ycGULtsI0nVgZktB9VuWz9wkphzlEZbiIdApeUa9ow4MMQ== 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=ZaNnbjJY; 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 26D17608362E; Sat, 7 Nov 2026 15:02:36 +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=ZaNnbjJY Received: by smtp.kernel.org (Postfix) with ESMTPSA id C979B1F0089F; Sat, 7 Nov 2026 15:02:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1794063756; bh=B9+LbpOXpCowFeJY6JPWOWJvaSEnuV52DkSgT0FGH0g=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=ZaNnbjJYBzuPS38oAxxhIo0YKXBeVjQhJ2o9Pum5sYoRS3hE0/LBo+rlM7c3wnEYh mz3O3twgFNnKb30HQWvedUm/jZ0nThxbG6T1wHSvGOkJTwmSQFFsCbI8+IYfZU+bYy vUAGoV/fBQkfkWIIMk6eFDyFt8rOx4MaQtEkqsj0= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Baolin Wang , Lance Yang , Zhao Gongyi , Catalin Marinas , Sasha Levin Subject: [PATCH 6.18 811/869] arm64/mm: restrict transparent contpte mappings to valid PTEs Date: Sat, 7 Nov 2026 08:58:13 -0500 Message-ID: <20261107134920.534027270@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261107134852.069646174@linuxfoundation.org> References: <20261107134852.069646174@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 6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Zhao Gongyi [ Upstream commit 486d396b19e93f6e56e0a0ba96c14a9ccc1a5977 ] The transparent contpte layer treats PTE_CONT as software grouping state. When a valid PTE has PTE_CONT set, the contpte helpers may align an operation to a CONT_PTE_SIZE block and operate on the whole block. The current single-PTE helpers use pte_valid_cont() to identify such groups; this is a helper contract, not an architectural restriction on using PTE_CONT with present-invalid descriptors. Explicit users such as hugetlb manage their contiguous encodings separately. contpte_set_ptes() currently sets PTE_CONT from alignment alone. Batched set_ptes() users can therefore install present-invalid PTEs with PTE_CONT set, for example mprotect(PROT_NONE), NUMA hinting through modify_prot_commit_ptes(), fork() copying a PROT_NONE large folio, or a PMD split installing PAGE_NONE PTEs. This is not a hardware programming problem: invalid descriptors are not translated, so the hardware ignores descriptor bits such as PTE_CONT. It is a software-state problem. Some arm64 fast paths, such as test_and_clear_young_ptes(), test pte_cont() directly instead of pte_valid_cont(). In the observed failure, mprotect(PROT_NONE) installed a full CONT_PTE_SIZE range of present-invalid PTEs with PTE_CONT set. MADV_GUARD_INSTALL then zapped one PTE. The nr == 1 clear_full_ptes() path only unfolds pte_valid_cont() entries, so the neighbouring present-invalid entries kept PTE_CONT while the target entry became a guard marker. clear_refs_pte_range() then reached the marker through: ptep_test_and_clear_young() test_and_clear_young_ptes() contpte_test_and_clear_young_ptes() contpte_align_addr_ptep() __ptep_test_and_clear_young() The marker changed from old_pte=0x00000000000047c0 to new_pte=0x00000000000043c0 by clearing PTE_AF. For swap PTEs, bit 10 is part of the swap type field, bits 6-10: 0x47c0 is SWP_PTE_MARKER with offset 4, while 0x43c0 has type 15 and is decoded as an ordinary swap entry. Zap later warned in swap_put_entries_direct() with a bad swap entry. Present-invalid PTEs could retain PTE_CONT as software grouping state, but their single-PTE modification paths would then need to recognize and unfold those groups consistently. Since current helpers mostly use pte_valid_cont() for membership, avoid creating present-invalid transparent contpte groups in contpte_set_ptes(). They bring no hardware benefit while invalid, and eligible valid ranges can be grouped again when they are installed. The public set_ptes() wrapper already clears PTE_CONT before calling contpte_set_ptes(). Return invalid PTEs through __set_ptes() directly, and warn if a future direct caller unexpectedly passes an invalid PTE with PTE_CONT set. This is triggerable by a user process against its own address space. On systems running with panic_on_warn, the warning becomes a denial of service. Fixes: 4602e5757bcc ("arm64/mm: wire up PTE_CONT for user mappings") Cc: stable@vger.kernel.org Reviewed-by: Baolin Wang Tested-by: Lance Yang Signed-off-by: Zhao Gongyi Signed-off-by: Catalin Marinas Signed-off-by: Sasha Levin --- arch/arm64/include/asm/pgtable.h | 3 +++ arch/arm64/mm/contpte.c | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index 1765e484fb9f0..2ce69d64e60ca 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -1675,6 +1675,9 @@ extern void modify_prot_commit_ptes(struct vm_area_struct *vma, unsigned long ad * The contpte APIs are used to transparently manage the contiguous bit in ptes * where it is possible and makes sense to do so. The PTE_CONT bit is considered * a private implementation detail of the public ptep API (see below). + * Single-PTE transparent contpte helpers use pte_valid_cont() to identify + * grouped PTEs; explicit contiguous-encoding users such as hugetlb manage + * their entries separately. */ extern void __contpte_try_fold(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte); diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c index 29024e20e876d..c39a290c6b5a2 100644 --- a/arch/arm64/mm/contpte.c +++ b/arch/arm64/mm/contpte.c @@ -444,8 +444,10 @@ void contpte_set_ptes(struct mm_struct *mm, unsigned long addr, */ VM_WARN_ON(nr == 1); - if (!mm_is_user(mm)) + if (!mm_is_user(mm) || !pte_valid(pte)) { + VM_WARN_ON_ONCE(!pte_valid(pte) && pte_cont(pte)); return __set_ptes(mm, addr, ptep, pte, nr); + } end = addr + (nr << PAGE_SHIFT); pfn = pte_pfn(pte); -- 2.53.0