summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authorcperciva <cperciva@FreeBSD.org>2010-11-25 22:06:07 +0000
committercperciva <cperciva@FreeBSD.org>2010-11-25 22:06:07 +0000
commit2b320b89cfe0888454773412b8c48f36acf6c79a (patch)
tree35c7cac6d06bd71b7677d6c801cd680507efd42a /sys/i386
parent701321ab36df75b6ea907f1457e0e7e2a626f6d6 (diff)
downloadFreeBSD-src-2b320b89cfe0888454773412b8c48f36acf6c79a.zip
FreeBSD-src-2b320b89cfe0888454773412b8c48f36acf6c79a.tar.gz
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
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/xen/pmap.c13
1 files changed, 1 insertions, 12 deletions
diff --git a/sys/i386/xen/pmap.c b/sys/i386/xen/pmap.c
index 7671dd9..b63089d 100644
--- a/sys/i386/xen/pmap.c
+++ b/sys/i386/xen/pmap.c
@@ -1292,19 +1292,7 @@ pmap_qenter(vm_offset_t sva, vm_page_t *ma, int count)
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();
OpenPOWER on IntegriCloud