summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorKurt Miller <kurt@cvs.openbsd.org>2008-11-24 03:19:43 +0000
committerKurt Miller <kurt@cvs.openbsd.org>2008-11-24 03:19:43 +0000
commitff062912a0a9a1ff25c0e74f75822f1650db9a0b (patch)
tree91a1536f8d25d7fe35129577da4fcb27b2651543 /sys/arch
parent182459c1837dd2aeab6973ad0c11d1fb9cc63bb1 (diff)
In pmap_write_protect() clear and set the protection bits atomically and
leave the rest alone. Also don't read *spte twice and compare results. feedback drahn@ okay art@ weingart@
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/i386/i386/pmap.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/sys/arch/i386/i386/pmap.c b/sys/arch/i386/i386/pmap.c
index 4a76de411d0..e8ec43d56f5 100644
--- a/sys/arch/i386/i386/pmap.c
+++ b/sys/arch/i386/i386/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.129 2008/11/24 03:13:22 kurt Exp $ */
+/* $OpenBSD: pmap.c,v 1.130 2008/11/24 03:19:42 kurt Exp $ */
/* $NetBSD: pmap.c,v 1.91 2000/06/02 17:46:37 thorpej Exp $ */
/*
@@ -2428,7 +2428,7 @@ void
pmap_write_protect(struct pmap *pmap, vaddr_t sva, vaddr_t eva,
vm_prot_t prot)
{
- pt_entry_t *ptes, *spte, *epte, npte;
+ pt_entry_t *ptes, *spte, *epte, npte, opte;
vaddr_t blockend;
u_int32_t md_prot;
vaddr_t va;
@@ -2480,11 +2480,14 @@ pmap_write_protect(struct pmap *pmap, vaddr_t sva, vaddr_t eva,
if (!pmap_valid_entry(*spte)) /* no mapping? */
continue;
- npte = (*spte & ~PG_PROT) | md_prot;
+ opte = *spte;
+ npte = (opte & ~PG_PROT) | md_prot;
- if (npte != *spte) {
+ if (npte != opte) {
pmap_exec_account(pmap, va, *spte, npte);
- i386_atomic_testset_ul(spte, npte);
+ i386_atomic_clearbits_l(spte,
+ (~md_prot & opte) & PG_PROT);
+ i386_atomic_setbits_l(spte, md_prot);
}
}
}