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],

Reply via email to