summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2021-09-11 18:08:33 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2021-09-11 18:08:33 +0000
commit29a328f62bbcf1d086dd895edcfb74f4a4cf2dfb (patch)
tree7527d1718532107d45348b7142ea65b4331a5024 /sys
parent7ae2424bc3059ea6830539931f90712e57d11f9e (diff)
Change the scope of the locking in pmap_extract() to prevent a race between
walking the page tables and another thread calling pmap_remove() that ends up removing a page table page. tested by sthen@ ok deraadt@, mpi@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/i386/i386/pmap.c5
-rw-r--r--sys/arch/i386/i386/pmapae.c5
2 files changed, 6 insertions, 4 deletions
diff --git a/sys/arch/i386/i386/pmap.c b/sys/arch/i386/i386/pmap.c
index a2f969fe23c..fe27c6703f2 100644
--- a/sys/arch/i386/i386/pmap.c
+++ b/sys/arch/i386/i386/pmap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.216 2021/09/06 12:59:59 mpi Exp $ */
+/* $OpenBSD: pmap.c,v 1.217 2021/09/11 18:08:32 kettenis Exp $ */
/* $NetBSD: pmap.c,v 1.91 2000/06/02 17:46:37 thorpej Exp $ */
/*
@@ -1545,8 +1545,8 @@ pmap_extract_86(struct pmap *pmap, vaddr_t va, paddr_t *pap)
{
pt_entry_t *ptes, pte;
+ ptes = pmap_map_ptes_86(pmap);
if (pmap_valid_entry(PDE(pmap, pdei(va)))) {
- ptes = pmap_map_ptes_86(pmap);
pte = ptes[atop(va)];
pmap_unmap_ptes_86(pmap);
if (!pmap_valid_entry(pte))
@@ -1555,6 +1555,7 @@ pmap_extract_86(struct pmap *pmap, vaddr_t va, paddr_t *pap)
*pap = (pte & PG_FRAME) | (va & ~PG_FRAME);
return 1;
}
+ pmap_unmap_ptes_86(pmap);
return 0;
}
diff --git a/sys/arch/i386/i386/pmapae.c b/sys/arch/i386/i386/pmapae.c
index ac171cb10d0..1a97cdbcc26 100644
--- a/sys/arch/i386/i386/pmapae.c
+++ b/sys/arch/i386/i386/pmapae.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmapae.c,v 1.64 2021/09/06 12:59:59 mpi Exp $ */
+/* $OpenBSD: pmapae.c,v 1.65 2021/09/11 18:08:32 kettenis Exp $ */
/*
* Copyright (c) 2006-2008 Michael Shalayeff
@@ -1048,8 +1048,8 @@ pmap_extract_pae(struct pmap *pmap, vaddr_t va, paddr_t *pap)
{
pt_entry_t *ptes, pte;
+ ptes = pmap_map_ptes_pae(pmap);
if (pmap_valid_entry(PDE(pmap, pdei(va)))) {
- ptes = pmap_map_ptes_pae(pmap);
pte = ptes[atop(va)];
pmap_unmap_ptes_pae(pmap);
if (!pmap_valid_entry(pte))
@@ -1058,6 +1058,7 @@ pmap_extract_pae(struct pmap *pmap, vaddr_t va, paddr_t *pap)
*pap = (pte & PG_FRAME) | (va & ~PG_FRAME);
return 1;
}
+ pmap_unmap_ptes_pae(pmap);
return 0;
}