diff options
author | alc <alc@FreeBSD.org> | 2004-07-26 18:10:10 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2004-07-26 18:10:10 +0000 |
commit | a47887d1fd56ccb2e8b27f8b25d2fa5e8ab1676b (patch) | |
tree | db2a0571c6b2981264f8818e829fa305c92c3518 /sys | |
parent | 73a684d5877f06cfed5b965bce4980dc1d1f3e5e (diff) | |
download | FreeBSD-src-a47887d1fd56ccb2e8b27f8b25d2fa5e8ab1676b.zip FreeBSD-src-a47887d1fd56ccb2e8b27f8b25d2fa5e8ab1676b.tar.gz |
Implement the protection check required by the pmap_extract_and_hold()
specification.
Reviewed and tested by: grehan@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/powerpc/aim/mmu_oea.c | 9 | ||||
-rw-r--r-- | sys/powerpc/powerpc/mmu_oea.c | 9 | ||||
-rw-r--r-- | sys/powerpc/powerpc/pmap.c | 9 |
3 files changed, 18 insertions, 9 deletions
diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c index d9ad966..c036860 100644 --- a/sys/powerpc/aim/mmu_oea.c +++ b/sys/powerpc/aim/mmu_oea.c @@ -1057,13 +1057,16 @@ pmap_extract(pmap_t pm, 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; + struct pvo_entry *pvo; vm_page_t m; m = NULL; mtx_lock(&Giant); - if ((pa = pmap_extract(pmap, va)) != 0) { - m = PHYS_TO_VM_PAGE(pa); + pvo = pmap_pvo_find_va(pmap, va & ~ADDR_POFF, NULL); + if (pvo != NULL && (pvo->pvo_pte.pte_hi & PTE_VALID) && + ((pvo->pvo_pte.pte_lo & PTE_PP) == PTE_RW || + (prot & VM_PROT_WRITE) == 0)) { + m = PHYS_TO_VM_PAGE(pvo->pvo_pte.pte_lo & PTE_RPGN); vm_page_lock_queues(); vm_page_hold(m); vm_page_unlock_queues(); diff --git a/sys/powerpc/powerpc/mmu_oea.c b/sys/powerpc/powerpc/mmu_oea.c index d9ad966..c036860 100644 --- a/sys/powerpc/powerpc/mmu_oea.c +++ b/sys/powerpc/powerpc/mmu_oea.c @@ -1057,13 +1057,16 @@ pmap_extract(pmap_t pm, 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; + struct pvo_entry *pvo; vm_page_t m; m = NULL; mtx_lock(&Giant); - if ((pa = pmap_extract(pmap, va)) != 0) { - m = PHYS_TO_VM_PAGE(pa); + pvo = pmap_pvo_find_va(pmap, va & ~ADDR_POFF, NULL); + if (pvo != NULL && (pvo->pvo_pte.pte_hi & PTE_VALID) && + ((pvo->pvo_pte.pte_lo & PTE_PP) == PTE_RW || + (prot & VM_PROT_WRITE) == 0)) { + m = PHYS_TO_VM_PAGE(pvo->pvo_pte.pte_lo & PTE_RPGN); vm_page_lock_queues(); vm_page_hold(m); vm_page_unlock_queues(); diff --git a/sys/powerpc/powerpc/pmap.c b/sys/powerpc/powerpc/pmap.c index d9ad966..c036860 100644 --- a/sys/powerpc/powerpc/pmap.c +++ b/sys/powerpc/powerpc/pmap.c @@ -1057,13 +1057,16 @@ pmap_extract(pmap_t pm, 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; + struct pvo_entry *pvo; vm_page_t m; m = NULL; mtx_lock(&Giant); - if ((pa = pmap_extract(pmap, va)) != 0) { - m = PHYS_TO_VM_PAGE(pa); + pvo = pmap_pvo_find_va(pmap, va & ~ADDR_POFF, NULL); + if (pvo != NULL && (pvo->pvo_pte.pte_hi & PTE_VALID) && + ((pvo->pvo_pte.pte_lo & PTE_PP) == PTE_RW || + (prot & VM_PROT_WRITE) == 0)) { + m = PHYS_TO_VM_PAGE(pvo->pvo_pte.pte_lo & PTE_RPGN); vm_page_lock_queues(); vm_page_hold(m); vm_page_unlock_queues(); |