Add missing locking to pmap_extract(9) and pmap_unwire(9).
authorkettenis <kettenis@openbsd.org>
Fri, 31 Dec 2021 11:21:45 +0000 (11:21 +0000)
committerkettenis <kettenis@openbsd.org>
Fri, 31 Dec 2021 11:21:45 +0000 (11:21 +0000)
ok patrick@, mpi@

sys/arch/arm64/arm64/pmap.c

index a34968e..b3994c2 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmap.c,v 1.82 2021/10/26 14:13:57 patrick Exp $ */
+/* $OpenBSD: pmap.c,v 1.83 2021/12/31 11:21:45 kettenis Exp $ */
 /*
  * Copyright (c) 2008-2009,2014-2016 Dale Rahn <drahn@dalerahn.com>
  *
@@ -153,6 +153,10 @@ pmap_unlock(struct pmap *pmap)
                mtx_leave(&pmap->pm_mtx);
 }
 
+#define PMAP_ASSERT_LOCKED(pmap)                       \
+       if ((pmap) != pmap_kernel())                    \
+               MUTEX_ASSERT_LOCKED(&(pmap)->pm_mtx);
+
 /* virtual to physical helpers */
 static inline int
 VP_IDX0(vaddr_t va)
@@ -381,6 +385,8 @@ pmap_vp_remove(pmap_t pm, vaddr_t va)
        struct pmapvp3 *vp3;
        struct pte_desc *pted;
 
+       PMAP_ASSERT_LOCKED(pm);
+       
        if (pm->have_4_level_pt) {
                vp1 = pm->pm_vp.l0->vp[VP_IDX0(va)];
                if (vp1 == NULL) {
@@ -426,6 +432,8 @@ pmap_vp_enter(pmap_t pm, vaddr_t va, struct pte_desc *pted, int flags)
        struct pmapvp2 *vp2;
        struct pmapvp3 *vp3;
 
+       PMAP_ASSERT_LOCKED(pm);
+       
        if (pm->have_4_level_pt) {
                vp1 = pm->pm_vp.l0->vp[VP_IDX0(va)];
                if (vp1 == NULL) {
@@ -1520,20 +1528,19 @@ pmap_deactivate(struct proc *p)
  * Get the physical page address for the given pmap/virtual address.
  */
 int
-pmap_extract(pmap_t pm, vaddr_t va, paddr_t *pa)
+pmap_extract(pmap_t pm, vaddr_t va, paddr_t *pap)
 {
        struct pte_desc *pted;
 
+       pmap_lock(pm);
        pted = pmap_vp_lookup(pm, va, NULL);
-
-       if (pted == NULL)
-               return 0;
-
-       if (pted->pted_pte == 0)
+       if (!pted || !PTED_VALID(pted)) {
+               pmap_unlock(pm);
                return 0;
-
-       if (pa != NULL)
-               *pa = (pted->pted_pte & PTE_RPGN) | (va & PAGE_MASK);
+       }
+       if (pap != NULL)
+               *pap = (pted->pted_pte & PTE_RPGN) | (va & PAGE_MASK);
+       pmap_unlock(pm);
 
        return 1;
 }
@@ -2010,11 +2017,13 @@ pmap_unwire(pmap_t pm, vaddr_t va)
 {
        struct pte_desc *pted;
 
+       pmap_lock(pm);
        pted = pmap_vp_lookup(pm, va, NULL);
        if ((pted != NULL) && (pted->pted_va & PTED_VA_WIRED_M)) {
                pm->pm_stats.wired_count--;
                pted->pted_va &= ~PTED_VA_WIRED_M;
        }
+       pmap_unlock(pm);
 }
 
 void