diff options
author | alc <alc@FreeBSD.org> | 2004-06-15 07:41:44 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2004-06-15 07:41:44 +0000 |
commit | 1ccccce78d56798f6791cfc2f4aab0d99e030f6d (patch) | |
tree | 84a0e18728a1b8a871c1c7ae29454889db0a94f2 /sys/amd64 | |
parent | 60240199d88180cd515f110185edaaa22d968cb2 (diff) | |
download | FreeBSD-src-1ccccce78d56798f6791cfc2f4aab0d99e030f6d.zip FreeBSD-src-1ccccce78d56798f6791cfc2f4aab0d99e030f6d.tar.gz |
Add pmap locking to pmap_extract(), pmap_mincore(), and pmap_remove().
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/pmap.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 46a0d4f..0816bfa 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -774,19 +774,23 @@ pmap_extract(pmap, va) if (pmap == 0) return 0; + PMAP_LOCK(pmap); pdep = pmap_pde(pmap, va); if (pdep) { pde = *pdep; if (pde) { if ((pde & PG_PS) != 0) { rtval = (pde & ~PDRMASK) | (va & PDRMASK); + PMAP_UNLOCK(pmap); return rtval; } pte = pmap_pte(pmap, va); rtval = ((*pte & PG_FRAME) | (va & PAGE_MASK)); + PMAP_UNLOCK(pmap); return rtval; } } + PMAP_UNLOCK(pmap); return 0; } @@ -1540,6 +1544,7 @@ pmap_remove_page(pmap_t pmap, vm_offset_t va) { pt_entry_t *pte; + PMAP_LOCK_ASSERT(pmap, MA_OWNED); pte = pmap_pte(pmap, va); if (pte == NULL || (*pte & PG_V) == 0) return; @@ -1566,8 +1571,12 @@ pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) if (pmap == NULL) return; + /* + * Perform an unsynchronized read. This is, however, safe. + */ if (pmap->pm_stats.resident_count == 0) return; + PMAP_LOCK(pmap); /* * special handling of removing one page. a very @@ -1578,6 +1587,7 @@ pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) pde = pmap_pde(pmap, sva); if (pde && (*pde & PG_PS) == 0) { pmap_remove_page(pmap, sva); + PMAP_UNLOCK(pmap); return; } } @@ -1648,6 +1658,7 @@ pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) if (anyvalid) pmap_invalidate_all(pmap); + PMAP_UNLOCK(pmap); } /* @@ -2791,12 +2802,12 @@ pmap_mincore(pmap, addr) vm_page_t m; int val = 0; + PMAP_LOCK(pmap); ptep = pmap_pte(pmap, addr); - if (ptep == 0) { - return 0; - } + pte = (ptep != NULL) ? *ptep : 0; + PMAP_UNLOCK(pmap); - if ((pte = *ptep) != 0) { + if (pte != 0) { vm_paddr_t pa; val = MINCORE_INCORE; |