Source-Changes-HG archive

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

[src/trunk]: src/sys/arch [merging from cherry-xenmp] make pmap_kernel() shad...



details:   https://anonhg.NetBSD.org/src/rev/1c656e375d83
branches:  trunk
changeset: 771027:1c656e375d83
user:      cherry <cherry%NetBSD.org@localhost>
date:      Sun Nov 06 15:18:18 2011 +0000

description:
[merging from cherry-xenmp] make pmap_kernel() shadow PMD per-cpu and MP aware.

diffstat:

 sys/arch/amd64/include/pmap.h |    5 +-
 sys/arch/i386/include/pmap.h  |   11 +--
 sys/arch/x86/include/cpu.h    |   20 ++--
 sys/arch/x86/x86/pmap.c       |  105 +++++++++++++++++++------
 sys/arch/xen/x86/cpu.c        |  173 ++++++++++++++++++++++++++++++++++-------
 sys/arch/xen/x86/x86_xpmap.c  |   37 ++++++--
 6 files changed, 265 insertions(+), 86 deletions(-)

diffs (truncated from 611 to 300 lines):

diff -r 3cf06510ede6 -r 1c656e375d83 sys/arch/amd64/include/pmap.h
--- a/sys/arch/amd64/include/pmap.h     Sun Nov 06 14:23:04 2011 +0000
+++ b/sys/arch/amd64/include/pmap.h     Sun Nov 06 15:18:18 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.h,v 1.27 2011/11/06 11:40:46 cherry Exp $ */
+/*     $NetBSD: pmap.h,v 1.28 2011/11/06 15:18:18 cherry Exp $ */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -192,7 +192,8 @@
 #define AL4_BASE ((pd_entry_t *)((char *)AL3_BASE + L4_SLOT_PTE * NBPD_L1))
 
 #define PDP_PDE                (L4_BASE + PDIR_SLOT_PTE)
-#define APDP_PDE       (L4_BASE + PDIR_SLOT_APTE)
+#define APDP_PDE       (&curcpu()->ci_kpm_pdir[PDIR_SLOT_APTE])
+#define APDP_PDE_SHADOW        (L4_BASE + PDIR_SLOT_APTE)
 
 #define PDP_BASE       L4_BASE
 #define APDP_BASE      AL4_BASE
diff -r 3cf06510ede6 -r 1c656e375d83 sys/arch/i386/include/pmap.h
--- a/sys/arch/i386/include/pmap.h      Sun Nov 06 14:23:04 2011 +0000
+++ b/sys/arch/i386/include/pmap.h      Sun Nov 06 15:18:18 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.h,v 1.111 2011/11/06 11:40:46 cherry Exp $        */
+/*     $NetBSD: pmap.h,v 1.112 2011/11/06 15:18:18 cherry Exp $        */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -277,7 +277,7 @@
  * mapping, because it points to the shadow PD. Use the kernel PD instead,
  * which is static
  */
-#define APDP_PDE       (&pmap_kl2pd[l2tol2(PDIR_SLOT_APTE)])
+#define APDP_PDE       (&curcpu()->ci_kpm_pdir[l2tol2(PDIR_SLOT_APTE)])
 #define APDP_PDE_SHADOW        (L2_BASE + PDIR_SLOT_APTE)
 #else /* PAE && XEN */
 #define APDP_PDE       (L2_BASE + PDIR_SLOT_APTE)
@@ -428,13 +428,6 @@
 
 #endif
 
-#ifdef PAE
-/* Address of the static kernel's L2 page */
-pd_entry_t *pmap_kl2pd;
-paddr_t pmap_kl2paddr;
-#endif
-
-
 struct trapframe;
 
 int    pmap_exec_fixup(struct vm_map *, struct trapframe *, struct pcb *);
diff -r 3cf06510ede6 -r 1c656e375d83 sys/arch/x86/include/cpu.h
--- a/sys/arch/x86/include/cpu.h        Sun Nov 06 14:23:04 2011 +0000
+++ b/sys/arch/x86/include/cpu.h        Sun Nov 06 15:18:18 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu.h,v 1.40 2011/11/01 21:21:32 joerg Exp $   */
+/*     $NetBSD: cpu.h,v 1.41 2011/11/06 15:18:18 cherry Exp $  */
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -176,16 +176,19 @@
 #endif
 
 #ifdef PAE
-       uint32_t        ci_pae_l3_pdirpa; /* PA of L3 PD */
+       paddr_t ci_pae_l3_pdirpa; /* PA of L3 PD */
        pd_entry_t *    ci_pae_l3_pdir; /* VA pointer to L3 PD */
 #endif
 
-#if defined(XEN) && defined(__x86_64__)
+#if defined(XEN) && (defined(PAE) || defined(__x86_64__))
        /* Currently active user PGD (can't use rcr3() with Xen) */
-       pd_entry_t *    ci_kpm_pdir;    /* per-cpu L4 PD (va) */
-       paddr_t         ci_kpm_pdirpa; /* per-cpu L4 PD (pa) */
+       pd_entry_t *    ci_kpm_pdir;    /* per-cpu PMD (va) */
+       paddr_t         ci_kpm_pdirpa; /* per-cpu PMD (pa) */
+#if defined(__x86_64__)
        paddr_t         ci_xen_current_user_pgd;
-#endif
+#endif /* __x86_64__ */
+#endif /* XEN et.al */
+
 
        char *ci_doubleflt_stack;
        char *ci_ddbipi_stack;
@@ -233,11 +236,6 @@
        int             ci_padout __aligned(64);
 };
 
-#ifdef __x86_64__
-#define ci_pdirpa(ci, index) \
-       ((ci)->ci_kpm_pdirpa + (index) * sizeof(pd_entry_t))
-#endif /* __x86_64__ */
-
 /*
  * Macros to handle (some) trapframe registers for common x86 code.
  */
diff -r 3cf06510ede6 -r 1c656e375d83 sys/arch/x86/x86/pmap.c
--- a/sys/arch/x86/x86/pmap.c   Sun Nov 06 14:23:04 2011 +0000
+++ b/sys/arch/x86/x86/pmap.c   Sun Nov 06 15:18:18 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmap.c,v 1.137 2011/10/18 23:43:06 jym Exp $   */
+/*     $NetBSD: pmap.c,v 1.138 2011/11/06 15:18:18 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.137 2011/10/18 23:43:06 jym Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.138 2011/11/06 15:18:18 cherry Exp $");
 
 #include "opt_user_ldt.h"
 #include "opt_lockdebug.h"
@@ -211,13 +211,6 @@
 #include <xen/hypervisor.h>
 #endif
 
-/* flag to be used for kernel mappings: PG_u on Xen/amd64, 0 otherwise */
-#if defined(XEN) && defined(__x86_64__)
-#define PG_k PG_u
-#else
-#define PG_k 0
-#endif
-
 /*
  * general info:
  *
@@ -1513,10 +1506,17 @@
                if (newp < (NKL2_KIMG_ENTRIES * NBPD_L2))
                        HYPERVISOR_update_va_mapping (newp + KERNBASE,
                            xpmap_ptom_masked(newp) | PG_u | PG_V, UVMF_INVLPG);
+               /* Update the pmap_kernel() L4 shadow */
                xpq_queue_pte_update (
                    xpmap_ptom_masked(pdes_pa)
                    + (pl_i(0, level) * sizeof (pd_entry_t)),
                    xpmap_ptom_masked(newp) | PG_RW | PG_u | PG_V);
+               /* sync to per-cpu PD */
+               xpq_queue_pte_update(
+                       xpmap_ptom_masked(cpu_info_primary.ci_kpm_pdirpa +
+                           pl_i(0, PTP_LEVELS) *
+                           sizeof(pd_entry_t)),
+                       pmap_kernel()->pm_pdir[pl_i(0, PTP_LEVELS)]);
                pmap_pte_flush();
                level--;
                if (level <= 1)
@@ -1580,18 +1580,22 @@
  * pmap_cpu_init_late: perform late per-CPU initialization.
  */
 
+#ifndef XEN
 void
 pmap_cpu_init_late(struct cpu_info *ci)
 {
+       /*
+        * The BP has already its own PD page allocated during early
+        * MD startup.
+        */
+       if (ci == &cpu_info_primary)
+               return;
+
 #ifdef PAE
        int ret;
        struct pglist pg;
        struct vm_page *vmap;
 
-       /* The BP has already its own L3 page allocated in locore.S. */
-       if (ci == &cpu_info_primary)
-               return;
-
        /*
         * Allocate a page for the per-CPU L3 PD. cr3 being 32 bits, PA musts
         * resides below the 4GB boundary.
@@ -1617,6 +1621,7 @@
        pmap_update(pmap_kernel());
 #endif
 }
+#endif
 
 /*
  * p v _ e n t r y   f u n c t i o n s
@@ -1833,8 +1838,23 @@
                 * clear it before freeing
                 */
                if (pmap_pdirpa(pmap, 0) == curcpu()->ci_xen_current_user_pgd
-                   && level == PTP_LEVELS - 1)
+                   && level == PTP_LEVELS - 1) {
                        pmap_pte_set(&pmap_kernel()->pm_pdir[index], 0);
+                       /*
+                        * Update the per-cpu PD on all cpus the current
+                        * pmap is active on 
+                        */ 
+                       CPU_INFO_ITERATOR cii;
+                       struct cpu_info *ci;
+                       for (CPU_INFO_FOREACH(cii, ci)) {
+                               if (ci == NULL) {
+                                       continue;
+                               }
+                               if (ci->ci_cpumask & pmap->pm_cpus) {
+                                       pmap_pte_set(&ci->ci_kpm_pdir[index], 0);
+                               }
+                       }
+               }
 #  endif /*__x86_64__ */
                invaladdr = level == 1 ? (vaddr_t)ptes :
                    (vaddr_t)pdes[level - 2];
@@ -1934,6 +1954,21 @@
                        pmap_pte_set(&pmap_kernel()->pm_pdir[index],
                                (pd_entry_t) (pmap_pa2pte(pa)
                                        | PG_u | PG_RW | PG_V));
+                       /*
+                        * Update the per-cpu PD on all cpus the current
+                        * pmap is active on 
+                        */ 
+                       CPU_INFO_ITERATOR cii;
+                       struct cpu_info *ci;
+                       for (CPU_INFO_FOREACH(cii, ci)) {
+                               if (ci == NULL) {
+                                       continue;
+                               }
+                               if (ci->ci_cpumask & pmap->pm_cpus) {
+                                       pmap_pte_set(&ci->ci_kpm_pdir[index],
+                                                    (pd_entry_t) (pmap_pa2pte(pa) | PG_u | PG_RW | PG_V));
+                               }
+                       }
                }
 #endif /* XEN && __x86_64__ */
                pmap_pte_flush();
@@ -2621,7 +2656,8 @@
        /* should be able to take ipis. */
        KASSERT(ci->ci_ilevel < IPL_HIGH); 
 #ifdef XEN
-       /* XXX not yet KASSERT(x86_read_psl() != 0); */
+       /* Check to see if interrupts are enabled (ie; no events are masked) */
+       KASSERT(x86_read_psl() == 0);
 #else
        KASSERT((x86_read_psl() & PSL_I) != 0);
 #endif
@@ -4093,23 +4129,42 @@
 
 
                for (i = index; i <= endindex; i++) {
+                       pt_entry_t pte;
+
                        KASSERT(!pmap_valid_entry(pdep[i]));
                        pmap_get_physpage(va, level - 1, &pa);
+                       pte = pmap_pa2pte(pa) | PG_k | PG_V | PG_RW;
 #ifdef XEN
-                       xpq_queue_pte_update((level == PTP_LEVELS) ?
-                           xpmap_ptom(pmap_pdirpa(pmap_kernel(), i)) :
-                           xpmap_ptetomach(&pdep[i]),
-                           pmap_pa2pte(pa) | PG_k | PG_V | PG_RW);
+                       switch (level) {
+                       case PTP_LEVELS: 
+#if defined(PAE) || defined(__x86_64__)
+                               if (i >= PDIR_SLOT_KERN) {
+                                       /* update per-cpu PMDs on all cpus */
+                                       CPU_INFO_ITERATOR cii;
+                                       struct cpu_info *ci;
+                                       for (CPU_INFO_FOREACH(cii, ci)) {
+                                               if (ci == NULL) {
+                                                       continue;
+                                               }
 #ifdef PAE
-                       if (level == PTP_LEVELS &&  i > L2_SLOT_KERN) {
-                               /* update real kernel PD too */
+                                               xpq_queue_pte_update(
+                                                       xpmap_ptetomach(&ci->ci_kpm_pdir[l2tol2(i)]), pte);
+#elif defined(__x86_64__)
+                                               xpq_queue_pte_update(
+                                                       xpmap_ptetomach(&ci->ci_kpm_pdir[i]), pte);
+#endif /* PAE */
+                                       }
+                               }
+#endif /* PAE || __x86_64__ */
+                               /* FALLTHROUGH */
+
+                       default: /* All other levels */
                                xpq_queue_pte_update(
-                                   xpmap_ptetomach(&pmap_kl2pd[l2tol2(i)]),
-                                   pmap_pa2pte(pa) | PG_k | PG_V | PG_RW);
+                                       xpmap_ptetomach(&pdep[i]), 
+                                       pte);
                        }
-#endif
 #else /* XEN */
-                       pdep[i] = pmap_pa2pte(pa) | PG_k | PG_V | PG_RW;
+                       pdep[i] = pte;
 #endif /* XEN */
                        KASSERT(level != PTP_LEVELS || nkptp[level - 1] +
                            pl_i(VM_MIN_KERNEL_ADDRESS, level) == i);
diff -r 3cf06510ede6 -r 1c656e375d83 sys/arch/xen/x86/cpu.c
--- a/sys/arch/xen/x86/cpu.c    Sun Nov 06 14:23:04 2011 +0000
+++ b/sys/arch/xen/x86/cpu.c    Sun Nov 06 15:18:18 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu.c,v 1.69 2011/11/06 11:40:47 cherry Exp $  */
+/*     $NetBSD: cpu.c,v 1.70 2011/11/06 15:18:19 cherry Exp $  */
 /* NetBSD: cpu.c,v 1.18 2004/02/20 17:35:01 yamt Exp  */
 



Home | Main Index | Thread Index | Old Index