diff options
author | kib <kib@FreeBSD.org> | 2013-08-18 21:36:22 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2013-08-18 21:36:22 +0000 |
commit | 17c7e12452a08f448fd5a4204936d7b073e0dc1f (patch) | |
tree | 8090c377de586f7d10e88fac7a08c24e84bce578 /sys/amd64 | |
parent | 7bc0ae6019ebfae94a80ca21f770e5eeaaea6d17 (diff) | |
download | FreeBSD-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
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/pmap.c | 3 |
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 */ |