summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2013-08-18 21:36:22 +0000
committerkib <kib@FreeBSD.org>2013-08-18 21:36:22 +0000
commit17c7e12452a08f448fd5a4204936d7b073e0dc1f (patch)
tree8090c377de586f7d10e88fac7a08c24e84bce578
parent7bc0ae6019ebfae94a80ca21f770e5eeaaea6d17 (diff)
downloadFreeBSD-src-17c7e12452a08f448fd5a4204936d7b073e0dc1f.zip
FreeBSD-src-17c7e12452a08f448fd5a4204936d7b073e0dc1f.tar.gz
When code from r254064 in pmap_ts_referenced() drops pv lock and
blocks on a pmap lock, pmap_release() might proceed in parallel and destroy the pmap mutex, since unlocked pv lock allows to remove pv entry owned by the pmap. For now, gate the pmap_release() on write-locked pvh_global_lock. Since pmap_ts_release() does not unlock the global lock, pmap_release() would not destroy pmap mutex until the pmap_ts_referenced() finished. We cannot enter pmap_ts_referenced() and encounter a pv entry for the destroyed pmap if pmap_release() passed the global lock gate, since pmap_remove_pages() would finish earlier. Reported by: jeff, pho Reviewed by: alc Tested by: pho Sponsored by: The FreeBSD Foundation
-rw-r--r--sys/amd64/amd64/pmap.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 747b3b8..215a4f1 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -1959,6 +1959,9 @@ pmap_release(pmap_t pmap)
KASSERT(vm_radix_is_empty(&pmap->pm_root),
("pmap_release: pmap has reserved page table page(s)"));
+ rw_wlock(&pvh_global_lock);
+ rw_wunlock(&pvh_global_lock);
+
m = PHYS_TO_VM_PAGE(pmap->pm_pml4[PML4PML4I] & PG_FRAME);
for (i = 0; i < NKPML4E; i++) /* KVA */
OpenPOWER on IntegriCloud