> Date: Fri, 15 Aug 2025 11:51:18 +0200 > From: Martin Pieuchot <m...@grenadille.net> > > On 15/08/25(Fri) 09:39, Miod Vallat wrote: > > > Please don't. Keeping that page read-only is important for security. > > > Maybe if nobody cares about the amd64 and i386 pmaps we should just > > > delete those architectures? > > > > But remember, because the end argument was wrong (sz instead of va + > > sz), this call did *nothing*. > > > > At least the commented out code will be correct now. > > Exactly. Since you committed this code Mark it does nothing. That's > what I said in the original report it's dead code.
The original code (before I "broke" it) did an unmap of the memory. BTW that means we need to fix the comment. Anyway, I went back to those mails from march and I think I have a simple fix. This just adopts the idiom used by pmap_do_remove() which *must* work correctly for both userland and kernel addresses. I simply dropped those bogus "& PG_FRAME" statements. As the comments say they should be no-ops. And other architectures don't seem to care, which suggests the comment is right. And even if someone would pass in non-page-aligned addresses the code will still do the right thing anyway. Tested (with a diff to fix the uvm_map_protect() call) on amd64. Only compile tested on i386. But if we break things someone will fix it isn't it? ok? Index: arch/amd64/amd64/pmap.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/pmap.c,v retrieving revision 1.181 diff -u -p -r1.181 pmap.c --- arch/amd64/amd64/pmap.c 5 Jul 2025 22:54:53 -0000 1.181 +++ arch/amd64/amd64/pmap.c 15 Aug 2025 11:06:19 -0000 @@ -2155,7 +2155,7 @@ pmap_write_protect(struct pmap *pmap, va { pt_entry_t *spte, *epte; pt_entry_t clear = 0, set = 0; - vaddr_t blockend; + vaddr_t blkendva; int shootall = 0, shootself; vaddr_t va; paddr_t scr3; @@ -2163,10 +2163,6 @@ pmap_write_protect(struct pmap *pmap, va scr3 = pmap_map_ptes(pmap); shootself = (scr3 == 0); - /* should be ok, but just in case ... */ - sva &= PG_FRAME; - eva &= PG_FRAME; - if (!(prot & PROT_READ)) set |= pg_xo; if (!(prot & PROT_WRITE)) @@ -2177,10 +2173,11 @@ pmap_write_protect(struct pmap *pmap, va if ((eva - sva > 32 * PAGE_SIZE) && sva < VM_MIN_KERNEL_ADDRESS) shootall = 1; - for (va = sva; va < eva ; va = blockend) { - blockend = (va & L2_FRAME) + NBPD_L2; - if (blockend > eva) - blockend = eva; + for (va = sva; va < eva; va = blkendva) { + /* determine range of block */ + blkendva = x86_round_pdr(va + 1); + if (blkendva > eva) + blkendva = eva; /* * XXXCDC: our PTE mappings should never be write-protected! @@ -2205,7 +2202,7 @@ pmap_write_protect(struct pmap *pmap, va #endif spte = &PTE_BASE[pl1_i(va)]; - epte = &PTE_BASE[pl1_i(blockend)]; + epte = &PTE_BASE[pl1_i(blkendva)]; for (/*null */; spte < epte ; spte++) { if (!pmap_valid_entry(*spte)) Index: arch/i386/i386/pmap.c =================================================================== RCS file: /cvs/src/sys/arch/i386/i386/pmap.c,v retrieving revision 1.228 diff -u -p -r1.228 pmap.c --- arch/i386/i386/pmap.c 7 Apr 2025 17:37:31 -0000 1.228 +++ arch/i386/i386/pmap.c 15 Aug 2025 11:06:19 -0000 @@ -2111,24 +2111,21 @@ pmap_write_protect_86(struct pmap *pmap, vm_prot_t prot) { pt_entry_t *ptes, *spte, *epte, npte, opte; - vaddr_t blockend; + vaddr_t blkendva; u_int32_t md_prot; vaddr_t va; int shootall = 0; ptes = pmap_map_ptes_86(pmap); /* locks pmap */ - /* should be ok, but just in case ... */ - sva &= PG_FRAME; - eva &= PG_FRAME; - if ((eva - sva > 32 * PAGE_SIZE) && pmap != pmap_kernel()) shootall = 1; - for (va = sva; va < eva; va = blockend) { - blockend = (va & PD_MASK) + NBPD; - if (blockend > eva) - blockend = eva; + for (va = sva; va < eva; va = blkendva) { + /* determine range of block */ + blkendva = i386_round_pdr(va + 1); + if (blkendva > eva) + blkendva = eva; /* * XXXCDC: our PTE mappings should never be write-protected! @@ -2155,7 +2152,7 @@ pmap_write_protect_86(struct pmap *pmap, md_prot |= PG_RW; spte = &ptes[atop(va)]; - epte = &ptes[atop(blockend)]; + epte = &ptes[atop(blkendva)]; for (/*null */; spte < epte ; spte++, va += PAGE_SIZE) { Index: arch/i386/i386/pmapae.c =================================================================== RCS file: /cvs/src/sys/arch/i386/i386/pmapae.c,v retrieving revision 1.76 diff -u -p -r1.76 pmapae.c --- arch/i386/i386/pmapae.c 18 Mar 2025 22:12:12 -0000 1.76 +++ arch/i386/i386/pmapae.c 15 Aug 2025 11:06:19 -0000 @@ -1543,24 +1543,21 @@ pmap_write_protect_pae(struct pmap *pmap vm_prot_t prot) { pt_entry_t *ptes, *spte, *epte, npte, opte; - vaddr_t blockend; + vaddr_t blkendva; u_int64_t md_prot; vaddr_t va; int shootall = 0; ptes = pmap_map_ptes_pae(pmap); /* locks pmap */ - /* should be ok, but just in case ... */ - sva &= PG_FRAME; - eva &= PG_FRAME; - if ((eva - sva > 32 * PAGE_SIZE) && pmap != pmap_kernel()) shootall = 1; - for (va = sva; va < eva; va = blockend) { - blockend = (va & PD_MASK) + NBPD; - if (blockend > eva) - blockend = eva; + for (va = sva; va < eva; va = blkendva) { + /* determine range of block */ + blkendva = i386_round_pdr(va + 1); + if (blkendva > eva) + blkendva = eva; /* * XXXCDC: our PTE mappings should never be write-protected! @@ -1589,7 +1586,7 @@ pmap_write_protect_pae(struct pmap *pmap md_prot |= PG_RW; spte = &ptes[atop(va)]; - epte = &ptes[atop(blockend)]; + epte = &ptes[atop(blkendva)]; for (/*null */; spte < epte ; spte++, va += PAGE_SIZE) {