diff options
author | alc <alc@FreeBSD.org> | 2004-07-18 05:09:28 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2004-07-18 05:09:28 +0000 |
commit | 2662ae1f647f381009ee81306784f33a86271775 (patch) | |
tree | 227966cf1070b916e30230466b1e9b0457785c5c /sys | |
parent | e479e5c263f44f535044a1b285c21a3108e0afaf (diff) | |
download | FreeBSD-src-2662ae1f647f381009ee81306784f33a86271775.zip FreeBSD-src-2662ae1f647f381009ee81306784f33a86271775.tar.gz |
Only extract a physical address from a pte in pmap_extract() if the pte is
valid.
Implement the protection check required by the pmap_extract_and_hold()
specification. (This enables the elimination of Giant from that function.)
Diffstat (limited to 'sys')
-rw-r--r-- | sys/alpha/alpha/pmap.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/sys/alpha/alpha/pmap.c b/sys/alpha/alpha/pmap.c index 0ffbf9a..c4b77a8 100644 --- a/sys/alpha/alpha/pmap.c +++ b/sys/alpha/alpha/pmap.c @@ -751,8 +751,8 @@ pmap_extract(pmap_t pmap, vm_offset_t va) return (pa); PMAP_LOCK(pmap); pte = pmap_lev3pte(pmap, va); - if (pte != NULL) - pa = alpha_ptob(ALPHA_PTE_TO_PFN(*pte)); + if (pte != NULL && pmap_pte_v(pte)) + pa = pmap_pte_pa(pte); PMAP_UNLOCK(pmap); return (pa); } @@ -767,18 +767,22 @@ pmap_extract(pmap_t pmap, vm_offset_t va) vm_page_t pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot) { - vm_paddr_t pa; + pt_entry_t *pte; vm_page_t m; m = NULL; - mtx_lock(&Giant); - if ((pa = pmap_extract(pmap, va)) != 0) { - m = PHYS_TO_VM_PAGE(pa); - vm_page_lock_queues(); + if (pmap == NULL) + return (m); + vm_page_lock_queues(); + PMAP_LOCK(pmap); + pte = pmap_lev3pte(pmap, va); + if (pte != NULL && pmap_pte_v(pte) && + (*pte & pte_prot(pmap, prot)) == pte_prot(pmap, prot)) { + m = PHYS_TO_VM_PAGE(pmap_pte_pa(pte)); vm_page_hold(m); - vm_page_unlock_queues(); } - mtx_unlock(&Giant); + vm_page_unlock_queues(); + PMAP_UNLOCK(pmap); return (m); } |