summaryrefslogtreecommitdiffstats
path: root/sys/sun4v
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2010-05-16 23:45:10 +0000
committeralc <alc@FreeBSD.org>2010-05-16 23:45:10 +0000
commitf6c07c5b87dfdddf4b4438ac3df38c4c83125281 (patch)
tree5d19152403395b71d9fe26760d1b05201ce13b02 /sys/sun4v
parent9090794d6cc9b8867376522131d6ff69824038a7 (diff)
downloadFreeBSD-src-f6c07c5b87dfdddf4b4438ac3df38c4c83125281.zip
FreeBSD-src-f6c07c5b87dfdddf4b4438ac3df38c4c83125281.tar.gz
On entry to pmap_enter(), assert that the page is busy. While I'm
here, make the style of assertion used by pmap_enter() consistent across all architectures. On entry to pmap_remove_write(), assert that the page is neither unmanaged nor fictitious, since we cannot remove write access to either kind of page. With the push down of the page queues lock, pmap_remove_write() cannot condition its behavior on the state of the PG_WRITEABLE flag if the page is busy. Assert that the object containing the page is locked. This allows us to know that the page will neither become busy nor will PG_WRITEABLE be set on it while pmap_remove_write() is running. Correct a long-standing bug in vm_page_cowsetup(). We cannot possibly do copy-on-write-based zero-copy transmit on unmanaged or fictitious pages, so don't even try. Previously, the call to pmap_remove_write() would have failed silently.
Diffstat (limited to 'sys/sun4v')
-rw-r--r--sys/sun4v/sun4v/pmap.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/sys/sun4v/sun4v/pmap.c b/sys/sun4v/sun4v/pmap.c
index 34d7ed1..6117275 100644
--- a/sys/sun4v/sun4v/pmap.c
+++ b/sys/sun4v/sun4v/pmap.c
@@ -1061,6 +1061,8 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t m,
vm_page_t om;
int invlva;
+ KASSERT((m->oflags & VPO_BUSY) != 0,
+ ("pmap_enter: page %p is not busy", m));
if (pmap->pm_context)
DPRINTF("pmap_enter(va=%lx, pa=0x%lx, prot=%x)\n", va,
VM_PAGE_TO_PHYS(m), prot);
@@ -1737,7 +1739,17 @@ void
pmap_remove_write(vm_page_t m)
{
- if ((m->flags & PG_WRITEABLE) == 0)
+ KASSERT((m->flags & (PG_FICTITIOUS | PG_UNMANAGED)) == 0,
+ ("pmap_remove_write: page %p is not managed", m));
+
+ /*
+ * If the page is not VPO_BUSY, then PG_WRITEABLE cannot be set by
+ * another thread while the object is locked. Thus, if PG_WRITEABLE
+ * is clear, no page table entries need updating.
+ */
+ VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED);
+ if ((m->oflags & VPO_BUSY) == 0 &&
+ (m->flags & PG_WRITEABLE) == 0)
return;
vm_page_lock_queues();
tte_clear_phys_bit(m, VTD_SW_W|VTD_W);
OpenPOWER on IntegriCloud