summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/aim
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2012-03-24 22:32:19 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2012-03-24 22:32:19 +0000
commit30ea2f9f8629b61aa7e750ff6012a54b9912b1a8 (patch)
treebbcb6c99be44e1229f4b496df0d9ee7060930828 /sys/powerpc/aim
parentf471f92e45c62ed6880b7610b1cc2567ad4267b1 (diff)
downloadFreeBSD-src-30ea2f9f8629b61aa7e750ff6012a54b9912b1a8.zip
FreeBSD-src-30ea2f9f8629b61aa7e750ff6012a54b9912b1a8.tar.gz
Only call vm_page_dirty() on pages that are writable in order not to
confuse the VM.
Diffstat (limited to 'sys/powerpc/aim')
-rw-r--r--sys/powerpc/aim/mmu_oea64.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
index 5356cfe..6251d79 100644
--- a/sys/powerpc/aim/mmu_oea64.c
+++ b/sys/powerpc/aim/mmu_oea64.c
@@ -1889,6 +1889,7 @@ static void
moea64_pvo_protect(mmu_t mmu, pmap_t pm, struct pvo_entry *pvo, vm_prot_t prot)
{
uintptr_t pt;
+ uint64_t oldlo;
/*
* Grab the PTE pointer before we diddle with the cached PTE
@@ -1900,11 +1901,15 @@ moea64_pvo_protect(mmu_t mmu, pmap_t pm, struct pvo_entry *pvo, vm_prot_t prot)
/*
* Change the protection of the page.
*/
+ oldlo = pvo->pvo_pte.lpte.pte_lo;
pvo->pvo_pte.lpte.pte_lo &= ~LPTE_PP;
- pvo->pvo_pte.lpte.pte_lo |= LPTE_BR;
pvo->pvo_pte.lpte.pte_lo &= ~LPTE_NOEXEC;
if ((prot & VM_PROT_EXECUTE) == 0)
pvo->pvo_pte.lpte.pte_lo |= LPTE_NOEXEC;
+ if (prot & VM_PROT_WRITE)
+ pvo->pvo_pte.lpte.pte_lo |= LPTE_BW;
+ else
+ pvo->pvo_pte.lpte.pte_lo |= LPTE_BR;
/*
* If the PVO is in the page table, update that pte as well.
@@ -1921,9 +1926,11 @@ moea64_pvo_protect(mmu_t mmu, pmap_t pm, struct pvo_entry *pvo, vm_prot_t prot)
}
/*
- * Update vm about the REF/CHG bits if the page is managed.
+ * Update vm about the REF/CHG bits if the page is managed and we have
+ * removed write access.
*/
- if ((pvo->pvo_vaddr & PVO_MANAGED) == PVO_MANAGED) {
+ if ((pvo->pvo_vaddr & PVO_MANAGED) == PVO_MANAGED &&
+ (oldlo & LPTE_PP) != LPTE_BR && !(prot && VM_PROT_WRITE)) {
struct vm_page *pg;
pg = PHYS_TO_VM_PAGE(pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN);
@@ -2345,7 +2352,8 @@ moea64_pvo_remove(mmu_t mmu, struct pvo_entry *pvo)
/*
* Update vm about the REF/CHG bits if the page is managed.
*/
- if ((pvo->pvo_vaddr & PVO_MANAGED) == PVO_MANAGED) {
+ if ((pvo->pvo_vaddr & PVO_MANAGED) == PVO_MANAGED &&
+ (pvo->pvo_pte.lpte.pte_lo & LPTE_PP) != LPTE_BR) {
struct vm_page *pg;
pg = PHYS_TO_VM_PAGE(pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN);
OpenPOWER on IntegriCloud