svn commit: r215844 - head/sys/i386/xen

Colin Percival cperciva at FreeBSD.org
Thu Nov 25 22:06:08 UTC 2010


Author: cperciva
Date: Thu Nov 25 22:06:07 2010
New Revision: 215844
URL: http://svn.freebsd.org/changeset/base/215844

Log:
  Revert r215819 and fix the bug properly.  In pmap_qremove, paging table
  updates were being queued by pmap_kremove, but the queue wasn't being
  flushed; as a result, the updates didn't happen until *after* the call
  to pmap_invalidate_range, and old entries could stick around in the TLB.
  Adding a PT_UPDATES_FLUSH() call immediately before pmap_invalidate_range
  ensures that after the invalidation the TLB will be repopulated with the
  correct new entries.
  
  Thanks to:	kib, avg, alc

Modified:
  head/sys/i386/xen/pmap.c

Modified: head/sys/i386/xen/pmap.c
==============================================================================
--- head/sys/i386/xen/pmap.c	Thu Nov 25 21:51:43 2010	(r215843)
+++ head/sys/i386/xen/pmap.c	Thu Nov 25 22:06:07 2010	(r215844)
@@ -1292,19 +1292,7 @@ pmap_qenter(vm_offset_t sva, vm_page_t *
 		mclp->args[0] = va;
 		mclp->args[1] = (uint32_t)(pa & 0xffffffff);
 		mclp->args[2] = (uint32_t)(pa >> 32);
-#if 0
 		mclp->args[3] = (*pte & PG_V) ? UVMF_INVLPG|UVMF_ALL : 0;
-#else
-		/*
-		 * Somehow we seem to be ending up with pages which are in
-		 * the TLB in spite of not having PG_V set, resulting in
-		 * pages newly loaded into the bufcache not showing up
-		 * immediately (i.e., accessing them provides the old data).
-		 * As a workaround, always perform a TLB flush, even if the
-		 * old page didn't have PG_V.
-		 */
-		mclp->args[3] = UVMF_INVLPG|UVMF_ALL;
-#endif
 	
 		va += PAGE_SIZE;
 		pte++;
@@ -1348,6 +1336,7 @@ pmap_qremove(vm_offset_t sva, int count)
 		pmap_kremove(va);
 		va += PAGE_SIZE;
 	}
+	PT_UPDATES_FLUSH();
 	pmap_invalidate_range(kernel_pmap, sva, va);
 	critical_exit();
 	vm_page_unlock_queues();


More information about the svn-src-all mailing list