DragonFlyBSD Kernel Audit
DF-0978 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/platform/pc64/x86_64/pmap.c b/sys/platform/pc64/x86_64/pmap.c
--- a/sys/platform/pc64/x86_64/pmap.c
+++ b/sys/platform/pc64/x86_64/pmap.c
@@ -4839,6 +4839,9 @@
 
 			spin_lock_shared(&ipmap->pm_spin);
 			pt_pv = pv_entry_lookup(ipmap, pmap_pt_pindex(iva));
+			/* DF-0978: hold pt_pv across the dropped shared lock */
+			if (pt_pv && !pv_hold_try(pt_pv))
+				pt_pv = NULL;
 			spin_unlock_shared(&ipmap->pm_spin);
 
 			if (pt_pv) {
@@ -4848,6 +4851,7 @@
 				}
 				atomic_add_long(
 					&ipmap->pm_stats.resident_count, -1);
+				pv_drop(pt_pv);
 			}
 		}
 		if (ipte & ipmap->pmap_bits[PG_W_IDX])