Change the scope of the locking in pmap_extract() to prevent a race between
authorkettenis <kettenis@openbsd.org>
Sat, 11 Sep 2021 18:08:32 +0000 (18:08 +0000)
committerkettenis <kettenis@openbsd.org>
Sat, 11 Sep 2021 18:08:32 +0000 (18:08 +0000)
walking the page tables and another thread calling pmap_remove() that ends
up removing a page table page.

tested by sthen@
ok deraadt@, mpi@

sys/arch/i386/i386/pmap.c
sys/arch/i386/i386/pmapae.c

index a2f969f..fe27c67 100644 (file)
@@ -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;
 }
 
index ac171cb..1a97cdb 100644 (file)
@@ -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;
 }