summaryrefslogtreecommitdiffstats
path: root/sys/powerpc
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2004-07-26 18:10:10 +0000
committeralc <alc@FreeBSD.org>2004-07-26 18:10:10 +0000
commita47887d1fd56ccb2e8b27f8b25d2fa5e8ab1676b (patch)
treedb2a0571c6b2981264f8818e829fa305c92c3518 /sys/powerpc
parent73a684d5877f06cfed5b965bce4980dc1d1f3e5e (diff)
downloadFreeBSD-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/powerpc')
-rw-r--r--sys/powerpc/aim/mmu_oea.c9
-rw-r--r--sys/powerpc/powerpc/mmu_oea.c9
-rw-r--r--sys/powerpc/powerpc/pmap.c9
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();
OpenPOWER on IntegriCloud