diff options
author | nwhitehorn <nwhitehorn@FreeBSD.org> | 2012-04-11 21:56:55 +0000 |
---|---|---|
committer | nwhitehorn <nwhitehorn@FreeBSD.org> | 2012-04-11 21:56:55 +0000 |
commit | e1fa94aa4e8fd968fc27604ed8ae6d7c43d04a07 (patch) | |
tree | a472326e80d397418bb0c90f390a60c4a1ebefde | |
parent | 323a33eb5fa061d94317b04f27519e5f73aa54be (diff) | |
download | FreeBSD-src-e1fa94aa4e8fd968fc27604ed8ae6d7c43d04a07.zip FreeBSD-src-e1fa94aa4e8fd968fc27604ed8ae6d7c43d04a07.tar.gz |
Only manipulate the PGA_EXECUTABLE flag on managed pages. This is a proxy
for whether the page is physical. On dense phys mem systems (32-bit),
VM_PHYS_TO_PAGE will not return NULL for device memory pages if device
memory is above physical memory even if there is no allocated vm_page.
Attempting to use the returned page could then cause either memory
corruption or a page fault.
-rw-r--r-- | sys/powerpc/aim/mmu_oea64.c | 24 |
1 files changed, 10 insertions, 14 deletions
diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c index 9937c10..bc814e4 100644 --- a/sys/powerpc/aim/mmu_oea64.c +++ b/sys/powerpc/aim/mmu_oea64.c @@ -1906,17 +1906,15 @@ moea64_pvo_protect(mmu_t mmu, pmap_t pm, struct pvo_entry *pvo, vm_prot_t prot) /* * If the PVO is in the page table, update that pte as well. */ - if (pt != -1) { + if (pt != -1) MOEA64_PTE_CHANGE(mmu, pt, &pvo->pvo_pte.lpte, pvo->pvo_vpn); - if (pm != kernel_pmap && pg != NULL && - !(pg->aflags & PGA_EXECUTABLE) && - (pvo->pvo_pte.lpte.pte_lo & - (LPTE_I | LPTE_G | LPTE_NOEXEC)) == 0) { + if (pm != kernel_pmap && pg != NULL && !(pg->aflags & PGA_EXECUTABLE) && + (pvo->pvo_pte.lpte.pte_lo & (LPTE_I | LPTE_G | LPTE_NOEXEC)) == 0) { + if ((pg->oflags & VPO_UNMANAGED) == 0) vm_page_aflag_set(pg, PGA_EXECUTABLE); - moea64_syncicache(mmu, pm, PVO_VADDR(pvo), - pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN, PAGE_SIZE); - } + moea64_syncicache(mmu, pm, PVO_VADDR(pvo), + pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN, PAGE_SIZE); } /* @@ -2368,9 +2366,8 @@ moea64_pvo_remove(mmu_t mmu, struct pvo_entry *pvo) */ pg = PHYS_TO_VM_PAGE(pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN); - if ((pvo->pvo_vaddr & PVO_MANAGED) == PVO_MANAGED && - (pvo->pvo_pte.lpte.pte_lo & LPTE_PP) != LPTE_BR) { - if (pg != NULL) { + if ((pvo->pvo_vaddr & PVO_MANAGED) == PVO_MANAGED && pg != NULL) { + if ((pvo->pvo_pte.lpte.pte_lo & LPTE_PP) != LPTE_BR) { if (pvo->pvo_pte.lpte.pte_lo & LPTE_CHG) vm_page_dirty(pg); if (pvo->pvo_pte.lpte.pte_lo & LPTE_REF) @@ -2378,11 +2375,10 @@ moea64_pvo_remove(mmu_t mmu, struct pvo_entry *pvo) if (LIST_EMPTY(vm_page_to_pvoh(pg))) vm_page_aflag_clear(pg, PGA_WRITEABLE); } + if (LIST_EMPTY(vm_page_to_pvoh(pg))) + vm_page_aflag_clear(pg, PGA_EXECUTABLE); } - if (pg != NULL && LIST_EMPTY(vm_page_to_pvoh(pg))) - vm_page_aflag_clear(pg, PGA_EXECUTABLE); - moea64_pvo_entries--; moea64_pvo_remove_calls++; |