Author: marius
Date: Tue Jul  5 18:40:37 2011
New Revision: 223795
URL: http://svn.freebsd.org/changeset/base/223795

Log:
  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

Modified:
  head/sys/kern/vfs_bio.c
  head/sys/sparc64/sparc64/pmap.c

Modified: head/sys/kern/vfs_bio.c
==============================================================================
--- head/sys/kern/vfs_bio.c     Tue Jul  5 18:40:19 2011        (r223794)
+++ head/sys/kern/vfs_bio.c     Tue Jul  5 18:40:37 2011        (r223795)
@@ -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) {

Modified: head/sys/sparc64/sparc64/pmap.c
==============================================================================
--- head/sys/sparc64/sparc64/pmap.c     Tue Jul  5 18:40:19 2011        
(r223794)
+++ head/sys/sparc64/sparc64/pmap.c     Tue Jul  5 18:40:37 2011        
(r223795)
@@ -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);
 }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to