Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/x86/x86 Page tables are not writable under Xen, so ...



details:   https://anonhg.NetBSD.org/src/rev/dd71650538a3
branches:  trunk
changeset: 824993:dd71650538a3
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Sun Jun 25 12:42:40 2017 +0000

description:
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.

diffstat:

 sys/arch/x86/x86/pmap.c |  42 +++++++++++++++++++++++++++++-------------
 1 files changed, 29 insertions(+), 13 deletions(-)

diffs (105 lines):

diff -r ec05b6f1a2c2 -r dd71650538a3 sys/arch/x86/x86/pmap.c
--- a/sys/arch/x86/x86/pmap.c   Sun Jun 25 12:39:27 2017 +0000
+++ b/sys/arch/x86/x86/pmap.c   Sun Jun 25 12:42:40 2017 +0000
@@ -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 @@
        struct pmap *cpm;
 #if !defined(XEN) || !defined(__x86_64__)
        struct pmap *pm;
+       long old;
 #endif
-       long old;
        int s, i;
        long needed_kptp[PTP_LEVELS], target_nptp;
        bool invalidate = false;
@@ -4415,7 +4415,9 @@
        }
 
        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 @@
                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 @@
         * 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 @@
                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],



Home | Main Index | Thread Index | Old Index