summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/aim/mmu_oea64.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/powerpc/aim/mmu_oea64.c')
-rw-r--r--sys/powerpc/aim/mmu_oea64.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c
index 8b6453a..140e949 100644
--- a/sys/powerpc/aim/mmu_oea64.c
+++ b/sys/powerpc/aim/mmu_oea64.c
@@ -1485,29 +1485,57 @@ moea64_is_referenced(mmu_t mmu, vm_page_t m)
boolean_t
moea64_is_modified(mmu_t mmu, vm_page_t m)
{
+ boolean_t rv;
- if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
- return (FALSE);
+ KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
+ ("moea64_is_modified: page %p is not managed", m));
- return (moea64_query_bit(m, LPTE_CHG));
+ /*
+ * If the page is not VPO_BUSY, then PG_WRITEABLE cannot be
+ * concurrently set while the object is locked. Thus, if PG_WRITEABLE
+ * is clear, no PTEs can have LPTE_CHG set.
+ */
+ VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED);
+ if ((m->oflags & VPO_BUSY) == 0 &&
+ (m->flags & PG_WRITEABLE) == 0)
+ return (FALSE);
+ vm_page_lock_queues();
+ rv = moea64_query_bit(m, LPTE_CHG);
+ vm_page_unlock_queues();
+ return (rv);
}
void
moea64_clear_reference(mmu_t mmu, vm_page_t m)
{
- if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
- return;
+ KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
+ ("moea64_clear_reference: page %p is not managed", m));
+ vm_page_lock_queues();
moea64_clear_bit(m, LPTE_REF, NULL);
+ vm_page_unlock_queues();
}
void
moea64_clear_modify(mmu_t mmu, vm_page_t m)
{
- if ((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) != 0)
+ KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
+ ("moea64_clear_modify: page %p is not managed", m));
+ VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED);
+ KASSERT((m->oflags & VPO_BUSY) == 0,
+ ("moea64_clear_modify: page %p is busy", m));
+
+ /*
+ * If the page is not PG_WRITEABLE, then no PTEs can have LPTE_CHG
+ * set. If the object containing the page is locked and the page is
+ * not VPO_BUSY, then PG_WRITEABLE cannot be concurrently set.
+ */
+ if ((m->flags & PG_WRITEABLE) == 0)
return;
+ vm_page_lock_queues();
moea64_clear_bit(m, LPTE_CHG, NULL);
+ vm_page_unlock_queues();
}
/*
OpenPOWER on IntegriCloud