Module Name: src Committed By: jym Date: Sat May 7 17:52:26 UTC 2011
Modified Files: src/sys/arch/x86/x86 [jym-xensuspend]: pmap.c Log Message: Fix the (recurring) problem with APDPs and Xen: unmap all of them at suspend, and let MD parts remap them when they are needed. The issue is not PAE specific, this can be triggered with i386 and amd64. Xen evaluates mappings in a lazy fashion, and it can incorrectly detects recursive ones when they are pointing to inactive pmaps. Move a comment that explains the L2 shadow page unmapping code closer to the associated function, it makes more sense. Now, you can save/suspend all kind of NetBSD domUs, with xbd(4) and xennet(4) devices. Remaining bugs are in xbd(4) and xennet(4) resuming, where the mappings have to be updated before issuing more I/Os. More Linux code reading I guess... Stay tuned. XXX (note to myself): move away from the machdep.sleep_state sysctl. To generate a diff of this commit: cvs rdiff -u -r1.77.2.10 -r1.77.2.11 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.77.2.10 src/sys/arch/x86/x86/pmap.c:1.77.2.11 --- src/sys/arch/x86/x86/pmap.c:1.77.2.10 Mon May 2 22:49:57 2011 +++ src/sys/arch/x86/x86/pmap.c Sat May 7 17:52:26 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.77.2.10 2011/05/02 22:49:57 jym Exp $ */ +/* $NetBSD: pmap.c,v 1.77.2.11 2011/05/07 17:52:26 jym Exp $ */ /* * Copyright (c) 2007 Manuel Bouyer. @@ -142,7 +142,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.77.2.10 2011/05/02 22:49:57 jym Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.77.2.11 2011/05/07 17:52:26 jym Exp $"); #include "opt_user_ldt.h" #include "opt_lockdebug.h" @@ -729,24 +729,6 @@ (kernel && (pmap->pm_kernel_cpus & ci->ci_cpumask) != 0)); } -/* - * Flush the content of APDP_PDE - */ -static inline -void pmap_unmap_apdp_pde(void) { - - int i; - - for (i = 0; i < PDP_SIZE; i++) { - pmap_pte_set(&APDP_PDE[i], 0); -#ifdef PAE - /* clear current pmap shadow entries too */ - pmap_pte_set(&APDP_PDE_SHADOW[i], 0); -#endif - } - -} - #ifdef XEN /* * Flush all APDP entries found in pmaps @@ -762,16 +744,7 @@ s = splvm(); -#ifdef PAE - /* - * For PAE, there are two places where alternative recursive mappings - * could be found: in the L2 shadow pages, and the "real" L2 kernel - * page (pmap_kl2pd), which is unique and static. - * We first clear the APDP for the current pmap. As L2 kernel page is - * unique, we only need to do it once for all pmaps. - */ - pmap_unmap_apdp_pde(); -#endif + pmap_unmap_apdp(); mutex_enter(&pmaps_lock); /* @@ -898,7 +871,15 @@ for (i = 0; i < PDP_SIZE; i++) { pmap_pte_set(APDP_PDE+i, 0); #if defined (XEN) && defined (PAE) - /* clear shadow entries too */ + /* + * For PAE, there are two places where alternative recursive + * mappings could be found with Xen: + * - in the L2 shadow pages + * - the "real" L2 kernel page (pmap_kl2pd), which is unique + * and static. + * We first clear the APDP for the current pmap. As L2 kernel + * page is unique, we only need to do it once for all pmaps. + */ pmap_pte_set(APDP_PDE_SHADOW+i, 0); #endif }