Module Name: src Committed By: bouyer Date: Sun Jun 25 12:42:40 UTC 2017
Modified Files: src/sys/arch/x86/x86: pmap.c Log Message: Page tables are not writable under Xen, so we can't memcpy() to them. Rewite to do the copy using pmap_pte_set() in the Xen case. To generate a diff of this commit: cvs rdiff -u -r1.252 -r1.253 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.252 src/sys/arch/x86/x86/pmap.c:1.253 --- src/sys/arch/x86/x86/pmap.c:1.252 Fri Jun 23 23:40:00 2017 +++ src/sys/arch/x86/x86/pmap.c Sun Jun 25 12:42:40 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.252 2017/06/23 23:40:00 jdolecek Exp $ */ +/* $NetBSD: pmap.c,v 1.253 2017/06/25 12:42:40 bouyer Exp $ */ /* * Copyright (c) 2008, 2010, 2016, 2017 The NetBSD Foundation, Inc. @@ -171,7 +171,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.252 2017/06/23 23:40:00 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.253 2017/06/25 12:42:40 bouyer Exp $"); #include "opt_user_ldt.h" #include "opt_lockdebug.h" @@ -4399,8 +4399,8 @@ pmap_growkernel(vaddr_t maxkvaddr) struct pmap *cpm; #if !defined(XEN) || !defined(__x86_64__) struct pmap *pm; -#endif long old; +#endif int s, i; long needed_kptp[PTP_LEVELS], target_nptp; bool invalidate = false; @@ -4415,7 +4415,9 @@ pmap_growkernel(vaddr_t maxkvaddr) } maxkvaddr = x86_round_pdr(maxkvaddr); +#if !defined(XEN) || !defined(__x86_64__) old = nkptp[PTP_LEVELS - 1]; +#endif /* Initialize needed_kptp. */ for (i = PTP_LEVELS - 1; i >= 1; i--) { @@ -4428,12 +4430,17 @@ pmap_growkernel(vaddr_t maxkvaddr) needed_kptp[i] = target_nptp - nkptp[i]; } +#if defined(XEN) && defined(__x86_64__) + /* only pmap_kernel() has kernel entries */ + cpm = kpm; +#else /* Get the current pmap */ if (__predict_true(cpu_info_primary.ci_flags & CPUF_PRESENT)) { cpm = curcpu()->ci_pmap; } else { cpm = kpm; } +#endif pmap_alloc_level(cpm, pmap_maxkvaddr, needed_kptp); @@ -4441,22 +4448,23 @@ pmap_growkernel(vaddr_t maxkvaddr) * If the number of top level entries changed, update all pmaps. */ if (needed_kptp[PTP_LEVELS - 1] != 0) { - size_t newpdes; - newpdes = nkptp[PTP_LEVELS - 1] - old; - - if (cpm != kpm) { - memcpy(&kpm->pm_pdir[PDIR_SLOT_KERN + old], - &cpm->pm_pdir[PDIR_SLOT_KERN + old], - newpdes * sizeof(pd_entry_t)); - } - #ifdef XEN #ifdef __x86_64__ /* nothing, kernel entries are never entered in user pmap */ #else /* __x86_64__ */ + int pdkidx; + if (cpm != kpm) { + for (pdkidx = PDIR_SLOT_KERN + old; + pdkidx < PDIR_SLOT_KERN + nkptp[PTP_LEVELS - 1]; + pdkidx++) { + pmap_pte_set(&kpm->pm_pdir[pdkidx], + cpm->pm_pdir[pdkidx]); + } + pmap_pte_flush(); + } + mutex_enter(&pmaps_lock); LIST_FOREACH(pm, &pmaps, pm_list) { - int pdkidx; for (pdkidx = PDIR_SLOT_KERN + old; pdkidx < PDIR_SLOT_KERN + nkptp[PTP_LEVELS - 1]; pdkidx++) { @@ -4468,6 +4476,14 @@ pmap_growkernel(vaddr_t maxkvaddr) mutex_exit(&pmaps_lock); #endif /* __x86_64__ */ #else /* XEN */ + size_t newpdes; + newpdes = nkptp[PTP_LEVELS - 1] - old; + if (cpm != kpm) { + memcpy(&kpm->pm_pdir[PDIR_SLOT_KERN + old], + &cpm->pm_pdir[PDIR_SLOT_KERN + old], + newpdes * sizeof(pd_entry_t)); + } + mutex_enter(&pmaps_lock); LIST_FOREACH(pm, &pmaps, pm_list) { memcpy(&pm->pm_pdir[PDIR_SLOT_KERN + old],