From nobody Sun Aug 10 23:23:40 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4c0Yjm66s3z63X9R; Sun, 10 Aug 2025 23:23:40 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4c0Yjm5Wdbz3fw9; Sun, 10 Aug 2025 23:23:40 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1754868220; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=bTV1n2rn8O5ncQ7YEFsZxal0VK6deHECM9OWXCP9bpQ=; b=thgNVTG8XVKi3LVNNNw4h02T52OBprfRCxsaPYgID1reyYnN980tnqotc5w4RaVxteyJdd xnKqp8JcD9AaR7X/26tsj7Mm1RxSncBM6xP+JB0ZcuS7rjlNjK9WO69mtayCivzedWnoEU 99lQoZjhYuCVugBTOBsPQQd+vdcKnr6bxJ4RzfLlbVb1rdFWt+hQK+VzSLzruJ2iHmLbMK DGvYfcpek4sfkTS1QQ8Ww4mnpWCKLuenwBBE7wryU8NNl7VLUP5+BIzuNm95XcuM9xQayS e0Idc/SbUqI8xXs7cMfszhEa7bbb30Sjtgd8xwQX7TP0NLRdvz2nDVBcT1sBHQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1754868220; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=bTV1n2rn8O5ncQ7YEFsZxal0VK6deHECM9OWXCP9bpQ=; b=H9eOmGLm+GH/Swmp8k5L5Z0cMQVNzZmSR1FNNkuT2XePxaw5QPZDxHup5yBWeuH8B/APC4 6Yxu665ALMtiEW73sqWC487WyrcTyy+bgQR4wEP1tTVF6Vg0q7lrv89EPsLKwFS5n9n1vp SglNj2mlJkZ4CwWnL0MD7cGfdOLNOGU1w2/3thzncpHA5aQ1iP7yULWv5UbeFadhm5Km8I 5/DSH+tM7zWMp4fQsyiSD+6NXhVGLVcgHqTl/QrzJZgMc7lUBgeQY4Uh1GVMl0H4oJcRes BVk37IpY5mKWeKViC0LTfzptt43w2JzTkPIO07Olc3FmrRnquFGjCGSuC9f/gg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1754868220; a=rsa-sha256; cv=none; b=kItZnAaUDDF5VFLdABHf7xgjL6DJ/ag3Bidv0RlYP4wsYsEuwT/UgfbPOIwZhCwR9j5idy mJWT06t7dlDh3bbOMkCst+pNpcBJ0fhoFq97DT1rX7X23dkT6eVcpuTr1BZXUl0ppJjoui XKD2pIAPJNgaoLGKn6I5aZN6bL1EgCatSSyDMHjmiSRgZc2FO2MrJWUby+G+T3z+mHg0kN 7EiB43My245DGqBy8EwybGypoMw79tXq6lSZzQIda70P2MQDpWLxItha10LNfN9zLKrGJ6 vA6Mk+dkP2ids3Tz+EKmPjDNTev5bmmTRy/8hlZdmrfi32UxqIRWLlwO74rSdA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4c0Yjm5145zBqt; Sun, 10 Aug 2025 23:23:40 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 57ANNevL054066; Sun, 10 Aug 2025 23:23:40 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 57ANNeqr054063; Sun, 10 Aug 2025 23:23:40 GMT (envelope-from git) Date: Sun, 10 Aug 2025 23:23:40 GMT Message-Id: <202508102323.57ANNeqr054063@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Alan Cox Subject: git: c0e04a22331e - stable/14 - arm64 pmap: do not panic when unable to insert PTP into trie List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: alc X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: c0e04a22331ebab8e639d69a0da7de71dd4119c3 Auto-Submitted: auto-generated The branch stable/14 has been updated by alc: URL: https://cgit.FreeBSD.org/src/commit/?id=c0e04a22331ebab8e639d69a0da7de71dd4119c3 commit c0e04a22331ebab8e639d69a0da7de71dd4119c3 Author: Alan Cox AuthorDate: 2025-07-08 23:31:26 +0000 Commit: Alan Cox CommitDate: 2025-08-10 16:01:06 +0000 arm64 pmap: do not panic when unable to insert PTP into trie When pmap_enter_l2() needs to destroy an existing kernel superpage mapping, do not remove the saved page table page (PTP) from the pm_root trie and remap it into the page table. Instead, simply zero it. Then, later the PTP does not need to be unmapped and reinserted into the trie. If the kernel region is not mapped by a superpage, then try to insert the PTP into the pm_root trie before clearing the PTEs. If the PTP insertion fails, then we can return failure with the old mappings still in place. Convert an assertion from a panic to a KASSERT. (cherry picked from commit 2cfd6342ac84c6915106fbe141795ca23a96cbba) --- sys/arm64/arm64/pmap.c | 84 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 30 deletions(-) diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index 8e3161736467..f8dec0d3a82b 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -464,7 +464,8 @@ static vm_page_t pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, static int pmap_enter_l2(pmap_t pmap, vm_offset_t va, pd_entry_t new_l2, u_int flags, vm_page_t m, struct rwlock **lockp); static int pmap_remove_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t sva, - pd_entry_t l1e, struct spglist *free, struct rwlock **lockp); + pd_entry_t l1e, bool demote_kl2e, struct spglist *free, + struct rwlock **lockp); static int pmap_remove_l3(pmap_t pmap, pt_entry_t *l3, vm_offset_t sva, pd_entry_t l2e, struct spglist *free, struct rwlock **lockp); static void pmap_reset_asid_set(pmap_t pmap); @@ -3411,8 +3412,7 @@ pmap_remove_kernel_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t va) PMAP_LOCK_ASSERT(pmap, MA_OWNED); ml3 = pmap_remove_pt_page(pmap, va); - if (ml3 == NULL) - panic("pmap_remove_kernel_l2: Missing pt page"); + KASSERT(ml3 != NULL, ("pmap_remove_kernel_l2: missing pt page")); ml3pa = VM_PAGE_TO_PHYS(ml3); newl2 = PHYS_TO_PTE(ml3pa) | L2_TABLE; @@ -3437,8 +3437,8 @@ pmap_remove_kernel_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t va) * pmap_remove_l2: Do the things to unmap a level 2 superpage. */ static int -pmap_remove_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t sva, - pd_entry_t l1e, struct spglist *free, struct rwlock **lockp) +pmap_remove_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t sva, pd_entry_t l1e, + bool demote_kl2e, struct spglist *free, struct rwlock **lockp) { struct md_page *pvh; pt_entry_t old_l2; @@ -3474,9 +3474,7 @@ pmap_remove_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t sva, vm_page_aflag_clear(mt, PGA_WRITEABLE); } } - if (pmap == kernel_pmap) { - pmap_remove_kernel_l2(pmap, l2, sva); - } else { + if (pmap != kernel_pmap) { ml3 = pmap_remove_pt_page(pmap, sva); if (ml3 != NULL) { KASSERT(vm_page_any_valid(ml3), @@ -3487,6 +3485,14 @@ pmap_remove_l2(pmap_t pmap, pt_entry_t *l2, vm_offset_t sva, ml3->ref_count = 0; pmap_add_delayed_free_list(ml3, free, FALSE); } + } else if (demote_kl2e) { + pmap_remove_kernel_l2(pmap, l2, sva); + } else { + ml3 = vm_radix_lookup(&pmap->pm_root, pmap_l2_pindex(sva)); + if (vm_page_any_valid(ml3)) { + ml3->valid = 0; + pmap_zero_page(ml3); + } } return (pmap_unuse_pt(pmap, sva, l1e, free)); } @@ -3689,7 +3695,7 @@ pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) if ((l3_paddr & ATTR_DESCR_MASK) == L2_BLOCK) { if (sva + L2_SIZE == va_next && eva >= va_next) { pmap_remove_l2(pmap, l2, sva, pmap_load(l1), - &free, &lock); + true, &free, &lock); continue; } else if (pmap_demote_l2_locked(pmap, l2, sva, &lock) == NULL) @@ -4849,33 +4855,51 @@ pmap_enter_l2(pmap_t pmap, vm_offset_t va, pd_entry_t new_l2, u_int flags, } } SLIST_INIT(&free); - if ((old_l2 & ATTR_DESCR_MASK) == L2_BLOCK) + if ((old_l2 & ATTR_DESCR_MASK) == L2_BLOCK) { (void)pmap_remove_l2(pmap, l2, va, - pmap_load(pmap_l1(pmap, va)), &free, lockp); - else + pmap_load(pmap_l1(pmap, va)), false, &free, lockp); + } else { + if (ADDR_IS_KERNEL(va)) { + /* + * Try to save the ptp in the trie + * before any changes to mappings are + * made. Abort on failure. + */ + mt = PHYS_TO_VM_PAGE(PTE_TO_PHYS(old_l2)); + if (pmap_insert_pt_page(pmap, mt, false, + false)) { + CTR1(KTR_PMAP, + "pmap_enter_l2: cannot ins kern ptp va %#lx", + va); + return (KERN_RESOURCE_SHORTAGE); + } + /* + * Both pmap_remove_l2() and + * pmap_remove_l3_range() will zero fill + * the L3 kernel page table page. + */ + } pmap_remove_l3_range(pmap, old_l2, va, va + L2_SIZE, &free, lockp); + if (ADDR_IS_KERNEL(va)) { + /* + * The TLB could have an intermediate + * entry for the L3 kernel page table + * page, so request an invalidation at + * all levels after clearing the + * L2_TABLE entry. + */ + pmap_clear(l2); + pmap_s1_invalidate_page(pmap, va, false); + } + } + KASSERT(pmap_load(l2) == 0, + ("pmap_enter_l2: non-zero L2 entry %p", l2)); if (!ADDR_IS_KERNEL(va)) { vm_page_free_pages_toq(&free, true); - KASSERT(pmap_load(l2) == 0, - ("pmap_enter_l2: non-zero L2 entry %p", l2)); } else { KASSERT(SLIST_EMPTY(&free), ("pmap_enter_l2: freed kernel page table page")); - - /* - * Both pmap_remove_l2() and pmap_remove_l3_range() - * will leave the kernel page table page zero filled. - * Nonetheless, the TLB could have an intermediate - * entry for the kernel page table page, so request - * an invalidation at all levels after clearing - * the L2_TABLE entry. - */ - mt = PHYS_TO_VM_PAGE(PTE_TO_PHYS(pmap_load(l2))); - if (pmap_insert_pt_page(pmap, mt, false, false)) - panic("pmap_enter_l2: trie insert failed"); - pmap_clear(l2); - pmap_s1_invalidate_page(pmap, va, false); } } @@ -7018,8 +7042,8 @@ pmap_demote_l2_abort(pmap_t pmap, vm_offset_t va, pt_entry_t *l2, struct spglist free; SLIST_INIT(&free); - (void)pmap_remove_l2(pmap, l2, va, pmap_load(pmap_l1(pmap, va)), &free, - lockp); + (void)pmap_remove_l2(pmap, l2, va, pmap_load(pmap_l1(pmap, va)), true, + &free, lockp); vm_page_free_pages_toq(&free, true); }