Date: Mon, 13 Apr 2026 14:24:05 +0000 From: Andrew Turner <andrew@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 580958427536 - main - arm64: Handle changing self-referential DMAP pages Message-ID: <69dcfc85.4722b.421b2c62@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=5809584275363d6b2f44981d8561a126a1344360 commit 5809584275363d6b2f44981d8561a126a1344360 Author: Andrew Turner <andrew@FreeBSD.org> AuthorDate: 2026-04-13 11:50:47 +0000 Commit: Andrew Turner <andrew@FreeBSD.org> CommitDate: 2026-04-13 14:23:05 +0000 arm64: Handle changing self-referential DMAP pages Support changing the property of a DMAP page that holds it's own page table entry. Because we need to perform a break-before-make sequence to change the properties of pages a page that also holds it's own page table entry will fault in the make part of the sequence. Handle this by mapping the page with a temporary mapping as we already do when demoting a superpage. Reviewed by: kib Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D55943 --- sys/arm64/arm64/pmap.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index 7d19c927d369..a23905994846 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -8248,6 +8248,7 @@ pmap_change_props_locked(vm_offset_t va, vm_size_t size, vm_prot_t prot, vm_paddr_t pa; pt_entry_t pte, *ptep, *newpte; pt_entry_t bits, mask; + char *tmpptep; int lvl, rv; PMAP_LOCK_ASSERT(kernel_pmap, MA_OWNED); @@ -8377,6 +8378,24 @@ pmap_change_props_locked(vm_offset_t va, vm_size_t size, vm_prot_t prot, break; } + tmpptep = 0; + if (tmpva <= (vm_offset_t)ptep && + tmpva + pte_size > (vm_offset_t)ptep) { + vm_paddr_t pte_pa; + + mtx_lock(&cmap_lock); + tmpptep = cmap1_addr; + pte_pa = DMAP_TO_PHYS((vm_offset_t)ptep); + pmap_store(cmap1_pte, ATTR_AF | + pmap_sh_attr | ATTR_S1_AP(ATTR_S1_AP_RW) | + ATTR_S1_XN | ATTR_KERN_GP | + ATTR_S1_IDX(VM_MEMATTR_WRITE_BACK) | + PHYS_TO_PTE(pte_pa &~L3_OFFSET) | L3_PAGE); + dsb(ishst); + ptep = (pt_entry_t *)(tmpptep + + ((vm_offset_t)ptep & PAGE_MASK)); + } + /* Update the entry */ pte = pmap_load(ptep); pte &= ~mask; @@ -8403,6 +8422,13 @@ pmap_change_props_locked(vm_offset_t va, vm_size_t size, vm_prot_t prot, break; } + if (tmpptep != 0) { + pmap_clear(cmap1_pte); + pmap_s1_invalidate_page(kernel_pmap, + (vm_offset_t)tmpptep, true); + mtx_unlock(&cmap_lock); + } + pa = PTE_TO_PHYS(pte); if (!VIRT_IN_DMAP(tmpva) && PHYS_IN_DMAP(pa)) { /*home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69dcfc85.4722b.421b2c62>
