Call pmap_qremove() before freeing or unwiring the pages, otherwise

there's a window during which a page can be re-used before its previous
mapping is removed.

Reviewed by:	alc
MFC after:	1 week
This commit is contained in:
marius 2011-07-05 18:40:37 +00:00
parent f71b110a36
commit 97f9011cd8
2 changed files with 6 additions and 4 deletions

View File

@ -1625,6 +1625,7 @@ vfs_vmio_release(struct buf *bp)
int i;
vm_page_t m;
pmap_qremove(trunc_page((vm_offset_t)bp->b_data), bp->b_npages);
VM_OBJECT_LOCK(bp->b_bufobj->bo_object);
for (i = 0; i < bp->b_npages; i++) {
m = bp->b_pages[i];
@ -1658,7 +1659,6 @@ vfs_vmio_release(struct buf *bp)
vm_page_unlock(m);
}
VM_OBJECT_UNLOCK(bp->b_bufobj->bo_object);
pmap_qremove(trunc_page((vm_offset_t) bp->b_data), bp->b_npages);
if (bp->b_bufsize) {
bufspacewakeup();
@ -3012,6 +3012,10 @@ allocbuf(struct buf *bp, int size)
if (desiredpages < bp->b_npages) {
vm_page_t m;
pmap_qremove((vm_offset_t)trunc_page(
(vm_offset_t)bp->b_data) +
(desiredpages << PAGE_SHIFT),
(bp->b_npages - desiredpages));
VM_OBJECT_LOCK(bp->b_bufobj->bo_object);
for (i = desiredpages; i < bp->b_npages; i++) {
/*
@ -3032,8 +3036,6 @@ allocbuf(struct buf *bp, int size)
vm_page_unlock(m);
}
VM_OBJECT_UNLOCK(bp->b_bufobj->bo_object);
pmap_qremove((vm_offset_t) trunc_page((vm_offset_t)bp->b_data) +
(desiredpages << PAGE_SHIFT), (bp->b_npages - desiredpages));
bp->b_npages = desiredpages;
}
} else if (size > bp->b_bcount) {

View File

@ -1294,6 +1294,7 @@ pmap_release(pmap_t pm)
pc->pc_pmap = NULL;
mtx_unlock_spin(&sched_lock);
pmap_qremove((vm_offset_t)pm->pm_tsb, TSB_PAGES);
obj = pm->pm_tsb_obj;
VM_OBJECT_LOCK(obj);
KASSERT(obj->ref_count == 1, ("pmap_release: tsbobj ref count != 1"));
@ -1305,7 +1306,6 @@ pmap_release(pmap_t pm)
vm_page_free_zero(m);
}
VM_OBJECT_UNLOCK(obj);
pmap_qremove((vm_offset_t)pm->pm_tsb, TSB_PAGES);
PMAP_LOCK_DESTROY(pm);
}