Module Name: src
Committed By: cherry
Date: Mon Jan 30 10:33:05 UTC 2012
Modified Files:
src/sys/arch/x86/x86: pmap.c
Log Message:
On xen, prevent cached PDP objects from being reused by pool_cache(9),
since they are "pinned" on the hypervisor and thus R/O for the domU.
Separately, after every per-cpu pmap pdir entry reset, make sure that
the corresponding L3 PTP pointers are flushed from all cpus with the
pmap loaded. Enforce this immediately via pmap_tlb_shootnow();
To generate a diff of this commit:
cvs rdiff -u -r1.160 -r1.161 src/sys/arch/x86/x86/pmap.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/x86/x86/pmap.c
diff -u src/sys/arch/x86/x86/pmap.c:1.160 src/sys/arch/x86/x86/pmap.c:1.161
--- src/sys/arch/x86/x86/pmap.c:1.160 Sun Jan 29 11:45:37 2012
+++ src/sys/arch/x86/x86/pmap.c Mon Jan 30 10:33:05 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.160 2012/01/29 11:45:37 drochner Exp $ */
+/* $NetBSD: pmap.c,v 1.161 2012/01/30 10:33:05 cherry Exp $ */
/*-
* Copyright (c) 2008, 2010 The NetBSD Foundation, Inc.
@@ -171,7 +171,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.160 2012/01/29 11:45:37 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.161 2012/01/30 10:33:05 cherry Exp $");
#include "opt_user_ldt.h"
#include "opt_lockdebug.h"
@@ -1614,7 +1614,7 @@ pmap_prealloc_lowmem_ptps(void)
void
pmap_init(void)
{
- int i;
+ int i, flags;
for (i = 0; i < PV_HASH_SIZE; i++) {
SLIST_INIT(&pv_hash_heads[i].hh_list);
@@ -1629,12 +1629,22 @@ pmap_init(void)
pool_cache_bootstrap(&pmap_cache, sizeof(struct pmap), 0, 0, 0,
"pmappl", NULL, IPL_NONE, NULL, NULL, NULL);
+
+#ifdef XEN
+ /*
+ * pool_cache(9) should not touch cached objects, since they
+ * are pinned on xen and R/O for the domU
+ */
+ flags = PR_NOTOUCH;
+#else /* XEN */
+ flags = 0;
+#endif /* XEN */
#ifdef PAE
- pool_cache_bootstrap(&pmap_pdp_cache, PAGE_SIZE * PDP_SIZE, 0, 0, 0,
+ pool_cache_bootstrap(&pmap_pdp_cache, PAGE_SIZE * PDP_SIZE, 0, 0, flags,
"pdppl", &pmap_pdp_allocator, IPL_NONE,
pmap_pdp_ctor, pmap_pdp_dtor, NULL);
#else /* PAE */
- pool_cache_bootstrap(&pmap_pdp_cache, PAGE_SIZE, 0, 0, 0,
+ pool_cache_bootstrap(&pmap_pdp_cache, PAGE_SIZE, 0, 0, flags,
"pdppl", NULL, IPL_NONE, pmap_pdp_ctor, pmap_pdp_dtor, NULL);
#endif /* PAE */
pool_cache_bootstrap(&pmap_pv_cache, sizeof(struct pv_entry), 0, 0,
@@ -1897,6 +1907,7 @@ pmap_free_ptp(struct pmap *pmap, struct
(vaddr_t)pdes[level - 2];
pmap_tlb_shootdown(pmap, invaladdr + index * PAGE_SIZE,
opde, TLBSHOOT_FREE_PTP1);
+ pmap_tlb_shootnow();
#else /* XEN */
invaladdr = level == 1 ? (vaddr_t)ptes :
(vaddr_t)pdes[level - 2];