From 1a48cf1747c39cd90cef462c6d8ba0cb89a74473 Mon Sep 17 00:00:00 2001 From: kettenis Date: Thu, 19 Jan 2023 20:17:11 +0000 Subject: [PATCH] Revise implementation of pmap_protect(9) in preparation for execute-only support. The current implementation doesn't handle the transition from RWX to RW correctly. Also generalize the pmap_write_protect() function in recognition of the fact that execute permission, write permission, and in the future read permission on executable pages, are handled by separate bits. ok deraadt@, mpi@ --- sys/arch/amd64/amd64/pmap.c | 14 ++++++++------ sys/arch/amd64/include/pmap.h | 12 +++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/sys/arch/amd64/amd64/pmap.c b/sys/arch/amd64/amd64/pmap.c index 893f840baf8..ea9b2c142e3 100644 --- a/sys/arch/amd64/amd64/pmap.c +++ b/sys/arch/amd64/amd64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.156 2022/11/29 21:41:39 guenther Exp $ */ +/* $OpenBSD: pmap.c,v 1.157 2023/01/19 20:17:11 kettenis Exp $ */ /* $NetBSD: pmap.c,v 1.3 2003/05/08 18:13:13 thorpej Exp $ */ /* @@ -2105,7 +2105,8 @@ pmap_clear_attrs(struct vm_page *pg, unsigned long clearbits) void pmap_write_protect(struct pmap *pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot) { - pt_entry_t nx, *spte, *epte; + pt_entry_t *spte, *epte; + pt_entry_t clear = 0, set = 0; vaddr_t blockend; int shootall = 0, shootself; vaddr_t va; @@ -2118,9 +2119,10 @@ pmap_write_protect(struct pmap *pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot) sva &= PG_FRAME; eva &= PG_FRAME; - nx = 0; + if (!(prot & PROT_WRITE)) + clear = PG_RW; if (!(prot & PROT_EXEC)) - nx = pg_nx; + set |= pg_nx; if ((eva - sva > 32 * PAGE_SIZE) && sva < VM_MIN_KERNEL_ADDRESS) shootall = 1; @@ -2158,8 +2160,8 @@ pmap_write_protect(struct pmap *pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot) for (/*null */; spte < epte ; spte++) { if (!pmap_valid_entry(*spte)) continue; - pmap_pte_clearbits(spte, PG_RW); - pmap_pte_setbits(spte, nx); + pmap_pte_clearbits(spte, clear); + pmap_pte_setbits(spte, set); } } diff --git a/sys/arch/amd64/include/pmap.h b/sys/arch/amd64/include/pmap.h index 4cfd83eb244..3660f440138 100644 --- a/sys/arch/amd64/include/pmap.h +++ b/sys/arch/amd64/include/pmap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.h,v 1.83 2023/01/17 19:29:09 kettenis Exp $ */ +/* $OpenBSD: pmap.h,v 1.84 2023/01/19 20:17:12 kettenis Exp $ */ /* $NetBSD: pmap.h,v 1.1 2003/04/26 18:39:46 fvdl Exp $ */ /* @@ -475,12 +475,10 @@ pmap_page_protect(struct vm_page *pg, vm_prot_t prot) static inline void pmap_protect(struct pmap *pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot) { - if ((prot & PROT_WRITE) == 0) { - if (prot & (PROT_READ| PROT_EXEC)) { - pmap_write_protect(pmap, sva, eva, prot); - } else { - pmap_remove(pmap, sva, eva); - } + if (prot != PROT_NONE) { + pmap_write_protect(pmap, sva, eva, prot); + } else { + pmap_remove(pmap, sva, eva); } } -- 2.20.1