summaryrefslogtreecommitdiffstats
path: root/sys/i386/xen/pmap.c
diff options
context:
space:
mode:
authorcperciva <cperciva@FreeBSD.org>2010-11-25 15:41:34 +0000
committercperciva <cperciva@FreeBSD.org>2010-11-25 15:41:34 +0000
commit4c7a0bc94aed5a25044e58618e0c6c2ca5a81748 (patch)
treefc95bf052d33c177f0cd7ead42a7ba54ae811301 /sys/i386/xen/pmap.c
parent008430e205fc0486471636b7b05c15ea15b18947 (diff)
downloadFreeBSD-src-4c7a0bc94aed5a25044e58618e0c6c2ca5a81748.zip
FreeBSD-src-4c7a0bc94aed5a25044e58618e0c6c2ca5a81748.tar.gz
Work around paging bug. Somehow we seem to be ending up with entries in
the TLB which don't correspond to ptes with PG_V set; prior to this commit I'm sometimes getting the wrong data when pages are loaded into the buffer cache (they're being loaded, but the missing TLB invalidation is causing the wrong data to be visible).
Diffstat (limited to 'sys/i386/xen/pmap.c')
-rw-r--r--sys/i386/xen/pmap.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/sys/i386/xen/pmap.c b/sys/i386/xen/pmap.c
index c44bf18..7671dd9 100644
--- a/sys/i386/xen/pmap.c
+++ b/sys/i386/xen/pmap.c
@@ -1292,7 +1292,19 @@ 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++;
OpenPOWER on IntegriCloud