Sat Feb 11 14:11:25 2017 UTC ()
Instead of using a global array with per-cpu indexes, embed the tmp VAs
into cpu_info directly. This concerns only {i386, Xen-i386, Xen-amd64},
because amd64 already has a direct map that is way faster than that.

There are two major issues with the global array: maxcpus entries are
allocated while it is unlikely that common i386 machines have so many
cpus, and the base VA of these entries is not cache-line-aligned, which
mostly guarantees cache-line-thrashing each time the VAs are entered.

Now the number of tmp VAs allocated is proportionate to the number of CPUs
attached (which therefore reduces memory consumption), and the base is
properly aligned.

On my 3-core AMD, the number of DC_refills_L2 events triggered when
performing 5x10^6 calls to pmap_zero_page on two dedicated cores is on
average divided by two with this patch.

Discussed on tech-kern a little.


(maxv)
diff -r1.67 -r1.68 src/sys/arch/x86/include/cpu.h
diff -r1.61 -r1.62 src/sys/arch/x86/include/pmap.h
diff -r1.122 -r1.123 src/sys/arch/x86/x86/cpu.c
diff -r1.239 -r1.240 src/sys/arch/x86/x86/pmap.c
diff -r1.108 -r1.109 src/sys/arch/xen/x86/cpu.c

cvs diff -r1.67 -r1.68 src/sys/arch/x86/include/cpu.h (expand / switch to unified diff)

--- src/sys/arch/x86/include/cpu.h 2015/12/13 15:02:19 1.67
+++ src/sys/arch/x86/include/cpu.h 2017/02/11 14:11:24 1.68
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cpu.h,v 1.67 2015/12/13 15:02:19 maxv Exp $ */ 1/* $NetBSD: cpu.h,v 1.68 2017/02/11 14:11:24 maxv Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1990 The Regents of the University of California. 4 * Copyright (c) 1990 The Regents of the University of California.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * William Jolitz. 8 * William Jolitz.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -123,26 +123,36 @@ struct cpu_info { @@ -123,26 +123,36 @@ struct cpu_info {
123 int ci_nintrhand; /* number of H/W interrupt handlers */ 123 int ci_nintrhand; /* number of H/W interrupt handlers */
124 uint64_t ci_scratch; 124 uint64_t ci_scratch;
125 uintptr_t ci_pmap_data[128 / sizeof(uintptr_t)]; 125 uintptr_t ci_pmap_data[128 / sizeof(uintptr_t)];
126 126
127#ifdef XEN 127#ifdef XEN
128 struct iplsource *ci_isources[NIPL]; 128 struct iplsource *ci_isources[NIPL];
129 u_long ci_evtmask[NR_EVENT_CHANNELS]; /* events allowed on this CPU */ 129 u_long ci_evtmask[NR_EVENT_CHANNELS]; /* events allowed on this CPU */
130#else 130#else
131 struct intrsource *ci_isources[MAX_INTR_SOURCES]; 131 struct intrsource *ci_isources[MAX_INTR_SOURCES];
132#endif 132#endif
133 volatile int ci_mtx_count; /* Negative count of spin mutexes */ 133 volatile int ci_mtx_count; /* Negative count of spin mutexes */
134 volatile int ci_mtx_oldspl; /* Old SPL at this ci_idepth */ 134 volatile int ci_mtx_oldspl; /* Old SPL at this ci_idepth */
135 135
 136#ifndef __HAVE_DIRECT_MAP
 137#define VPAGE_SRC 0
 138#define VPAGE_DST 1
 139#define VPAGE_ZER 2
 140#define VPAGE_PTP 3
 141#define VPAGE_MAX 4
 142 vaddr_t vpage[VPAGE_MAX];
 143 pt_entry_t *vpage_pte[VPAGE_MAX];
 144#endif
 145
136 /* The following must be aligned for cmpxchg8b. */ 146 /* The following must be aligned for cmpxchg8b. */
137 struct { 147 struct {
138 uint32_t ipending; 148 uint32_t ipending;
139 int ilevel; 149 int ilevel;
140 } ci_istate __aligned(8); 150 } ci_istate __aligned(8);
141#define ci_ipending ci_istate.ipending 151#define ci_ipending ci_istate.ipending
142#define ci_ilevel ci_istate.ilevel 152#define ci_ilevel ci_istate.ilevel
143 153
144 int ci_idepth; 154 int ci_idepth;
145 void * ci_intrstack; 155 void * ci_intrstack;
146 uint32_t ci_imask[NIPL]; 156 uint32_t ci_imask[NIPL];
147 uint32_t ci_iunmask[NIPL]; 157 uint32_t ci_iunmask[NIPL];
148 158

cvs diff -r1.61 -r1.62 src/sys/arch/x86/include/pmap.h (expand / switch to unified diff)

--- src/sys/arch/x86/include/pmap.h 2016/11/08 03:05:36 1.61
+++ src/sys/arch/x86/include/pmap.h 2017/02/11 14:11:24 1.62
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: pmap.h,v 1.61 2016/11/08 03:05:36 christos Exp $ */ 1/* $NetBSD: pmap.h,v 1.62 2017/02/11 14:11:24 maxv Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1997 Charles D. Cranor and Washington University. 4 * Copyright (c) 1997 Charles D. Cranor and Washington University.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -268,26 +268,30 @@ void pmap_pv_init(void); @@ -268,26 +268,30 @@ void pmap_pv_init(void);
268void pmap_pv_track(paddr_t, psize_t); 268void pmap_pv_track(paddr_t, psize_t);
269void pmap_pv_untrack(paddr_t, psize_t); 269void pmap_pv_untrack(paddr_t, psize_t);
270 270
271void pmap_map_ptes(struct pmap *, struct pmap **, pd_entry_t **, 271void pmap_map_ptes(struct pmap *, struct pmap **, pd_entry_t **,
272 pd_entry_t * const **); 272 pd_entry_t * const **);
273void pmap_unmap_ptes(struct pmap *, struct pmap *); 273void pmap_unmap_ptes(struct pmap *, struct pmap *);
274 274
275int pmap_pdes_invalid(vaddr_t, pd_entry_t * const *, pd_entry_t *); 275int pmap_pdes_invalid(vaddr_t, pd_entry_t * const *, pd_entry_t *);
276 276
277u_int x86_mmap_flags(paddr_t); 277u_int x86_mmap_flags(paddr_t);
278 278
279bool pmap_is_curpmap(struct pmap *); 279bool pmap_is_curpmap(struct pmap *);
280 280
 281#ifndef __HAVE_DIRECT_MAP
 282void pmap_vpage_cpu_init(struct cpu_info *);
 283#endif
 284
281vaddr_t reserve_dumppages(vaddr_t); /* XXX: not a pmap fn */ 285vaddr_t reserve_dumppages(vaddr_t); /* XXX: not a pmap fn */
282 286
283typedef enum tlbwhy { 287typedef enum tlbwhy {
284 TLBSHOOT_APTE, 288 TLBSHOOT_APTE,
285 TLBSHOOT_KENTER, 289 TLBSHOOT_KENTER,
286 TLBSHOOT_KREMOVE, 290 TLBSHOOT_KREMOVE,
287 TLBSHOOT_FREE_PTP1, 291 TLBSHOOT_FREE_PTP1,
288 TLBSHOOT_FREE_PTP2, 292 TLBSHOOT_FREE_PTP2,
289 TLBSHOOT_REMOVE_PTE, 293 TLBSHOOT_REMOVE_PTE,
290 TLBSHOOT_REMOVE_PTES, 294 TLBSHOOT_REMOVE_PTES,
291 TLBSHOOT_SYNC_PV1, 295 TLBSHOOT_SYNC_PV1,
292 TLBSHOOT_SYNC_PV2, 296 TLBSHOOT_SYNC_PV2,
293 TLBSHOOT_WRITE_PROTECT, 297 TLBSHOOT_WRITE_PROTECT,

cvs diff -r1.122 -r1.123 src/sys/arch/x86/x86/cpu.c (expand / switch to unified diff)

--- src/sys/arch/x86/x86/cpu.c 2017/02/02 08:57:04 1.122
+++ src/sys/arch/x86/x86/cpu.c 2017/02/11 14:11:24 1.123
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cpu.c,v 1.122 2017/02/02 08:57:04 maxv Exp $ */ 1/* $NetBSD: cpu.c,v 1.123 2017/02/11 14:11:24 maxv Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2000-2012 NetBSD Foundation, Inc. 4 * Copyright (c) 2000-2012 NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Bill Sommerfeld of RedBack Networks Inc, and by Andrew Doran. 8 * by Bill Sommerfeld of RedBack Networks Inc, and by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -52,27 +52,27 @@ @@ -52,27 +52,27 @@
52 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE 54 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE
55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 * SUCH DAMAGE. 61 * SUCH DAMAGE.
62 */ 62 */
63 63
64#include <sys/cdefs.h> 64#include <sys/cdefs.h>
65__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.122 2017/02/02 08:57:04 maxv Exp $"); 65__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.123 2017/02/11 14:11:24 maxv Exp $");
66 66
67#include "opt_ddb.h" 67#include "opt_ddb.h"
68#include "opt_mpbios.h" /* for MPDEBUG */ 68#include "opt_mpbios.h" /* for MPDEBUG */
69#include "opt_mtrr.h" 69#include "opt_mtrr.h"
70#include "opt_multiprocessor.h" 70#include "opt_multiprocessor.h"
71 71
72#include "lapic.h" 72#include "lapic.h"
73#include "ioapic.h" 73#include "ioapic.h"
74 74
75#include <sys/param.h> 75#include <sys/param.h>
76#include <sys/proc.h> 76#include <sys/proc.h>
77#include <sys/systm.h> 77#include <sys/systm.h>
78#include <sys/device.h> 78#include <sys/device.h>
@@ -276,26 +276,29 @@ cpu_vm_init(struct cpu_info *ci) @@ -276,26 +276,29 @@ cpu_vm_init(struct cpu_info *ci)
276 } 276 }
277 ncolors = picked; 277 ncolors = picked;
278 } 278 }
279 } 279 }
280 280
281 /* 281 /*
282 * Knowing the size of the largest cache on this CPU, potentially 282 * Knowing the size of the largest cache on this CPU, potentially
283 * re-color our pages. 283 * re-color our pages.
284 */ 284 */
285 aprint_debug_dev(ci->ci_dev, "%d page colors\n", ncolors); 285 aprint_debug_dev(ci->ci_dev, "%d page colors\n", ncolors);
286 uvm_page_recolor(ncolors); 286 uvm_page_recolor(ncolors);
287 287
288 pmap_tlb_cpu_init(ci); 288 pmap_tlb_cpu_init(ci);
 289#ifndef __HAVE_DIRECT_MAP
 290 pmap_vpage_cpu_init(ci);
 291#endif
289} 292}
290 293
291static void 294static void
292cpu_attach(device_t parent, device_t self, void *aux) 295cpu_attach(device_t parent, device_t self, void *aux)
293{ 296{
294 struct cpu_softc *sc = device_private(self); 297 struct cpu_softc *sc = device_private(self);
295 struct cpu_attach_args *caa = aux; 298 struct cpu_attach_args *caa = aux;
296 struct cpu_info *ci; 299 struct cpu_info *ci;
297 uintptr_t ptr; 300 uintptr_t ptr;
298#if NLAPIC > 0 301#if NLAPIC > 0
299 int cpunum = caa->cpu_number; 302 int cpunum = caa->cpu_number;
300#endif 303#endif
301 static bool again; 304 static bool again;

cvs diff -r1.239 -r1.240 src/sys/arch/x86/x86/pmap.c (expand / switch to unified diff)

--- src/sys/arch/x86/x86/pmap.c 2017/02/02 17:37:49 1.239
+++ src/sys/arch/x86/x86/pmap.c 2017/02/11 14:11:24 1.240
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: pmap.c,v 1.239 2017/02/02 17:37:49 maxv Exp $ */ 1/* $NetBSD: pmap.c,v 1.240 2017/02/11 14:11:24 maxv Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2008, 2010, 2016, 2017 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008, 2010, 2016, 2017 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran, and by Maxime Villard. 8 * by Andrew Doran, and by Maxime Villard.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -161,27 +161,27 @@ @@ -161,27 +161,27 @@
161 * Hibler/Jolitz pmap, as modified for FreeBSD by John S. Dyson 161 * Hibler/Jolitz pmap, as modified for FreeBSD by John S. Dyson
162 * and David Greenman. 162 * and David Greenman.
163 * 163 *
164 * [3] the Mach pmap. this pmap, from CMU, seems to have migrated 164 * [3] the Mach pmap. this pmap, from CMU, seems to have migrated
165 * between several processors. the VAX version was done by 165 * between several processors. the VAX version was done by
166 * Avadis Tevanian, Jr., and Michael Wayne Young. the i386 166 * Avadis Tevanian, Jr., and Michael Wayne Young. the i386
167 * version was done by Lance Berc, Mike Kupfer, Bob Baron, 167 * version was done by Lance Berc, Mike Kupfer, Bob Baron,
168 * David Golub, and Richard Draves. the alpha version was 168 * David Golub, and Richard Draves. the alpha version was
169 * done by Alessandro Forin (CMU/Mach) and Chris Demetriou 169 * done by Alessandro Forin (CMU/Mach) and Chris Demetriou
170 * (NetBSD/alpha). 170 * (NetBSD/alpha).
171 */ 171 */
172 172
173#include <sys/cdefs.h> 173#include <sys/cdefs.h>
174__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.239 2017/02/02 17:37:49 maxv Exp $"); 174__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.240 2017/02/11 14:11:24 maxv Exp $");
175 175
176#include "opt_user_ldt.h" 176#include "opt_user_ldt.h"
177#include "opt_lockdebug.h" 177#include "opt_lockdebug.h"
178#include "opt_multiprocessor.h" 178#include "opt_multiprocessor.h"
179#include "opt_xen.h" 179#include "opt_xen.h"
180 180
181#include <sys/param.h> 181#include <sys/param.h>
182#include <sys/systm.h> 182#include <sys/systm.h>
183#include <sys/proc.h> 183#include <sys/proc.h>
184#include <sys/pool.h> 184#include <sys/pool.h>
185#include <sys/kernel.h> 185#include <sys/kernel.h>
186#include <sys/atomic.h> 186#include <sys/atomic.h>
187#include <sys/cpu.h> 187#include <sys/cpu.h>
@@ -486,49 +486,35 @@ paddr_t local_apic_pa __read_mostly; @@ -486,49 +486,35 @@ paddr_t local_apic_pa __read_mostly;
486 486
487/* 487/*
488 * pool that pmap structures are allocated from 488 * pool that pmap structures are allocated from
489 */ 489 */
490static struct pool_cache pmap_cache; 490static struct pool_cache pmap_cache;
491 491
492/* 492/*
493 * pv_entry cache 493 * pv_entry cache
494 */ 494 */
495static struct pool_cache pmap_pv_cache; 495static struct pool_cache pmap_pv_cache;
496 496
497#ifndef __HAVE_DIRECT_MAP 497#ifndef __HAVE_DIRECT_MAP
498/* 498/*
499 * MULTIPROCESSOR: special VAs and PTEs are actually allocated inside a 
500 * (maxcpus * NPTECL) array of PTE, to avoid cache line thrashing due to 
501 * false sharing. 
502 */ 
503#ifdef MULTIPROCESSOR 
504#define PTESLEW(pte, id) ((pte)+(id)*NPTECL) 
505#define VASLEW(va,id) ((va)+(id)*NPTECL*PAGE_SIZE) 
506#else 
507#define PTESLEW(pte, id) ((void)id, pte) 
508#define VASLEW(va,id) ((void)id, va) 
509#endif 
510 
511/* 
512 * Special VAs and the PTEs that map them 499 * Special VAs and the PTEs that map them
513 */ 500 */
514static pt_entry_t *csrc_pte, *cdst_pte, *zero_pte, *ptp_pte, *early_zero_pte; 501static pt_entry_t *early_zero_pte;
515static char *csrcp, *cdstp, *zerop, *ptpp; 502static void pmap_vpage_cpualloc(struct cpu_info *);
516#ifdef XEN 503#ifdef XEN
517char *early_zerop; /* also referenced from xen_locore() */ 504char *early_zerop; /* also referenced from xen_locore() */
518#else 505#else
519static char *early_zerop; 506static char *early_zerop;
520#endif 507#endif
521 
522#endif 508#endif
523 509
524int pmap_enter_default(pmap_t, vaddr_t, paddr_t, vm_prot_t, u_int); 510int pmap_enter_default(pmap_t, vaddr_t, paddr_t, vm_prot_t, u_int);
525 511
526/* PDP pool_cache(9) and its callbacks */ 512/* PDP pool_cache(9) and its callbacks */
527struct pool_cache pmap_pdp_cache; 513struct pool_cache pmap_pdp_cache;
528static int pmap_pdp_ctor(void *, void *, int); 514static int pmap_pdp_ctor(void *, void *, int);
529static void pmap_pdp_dtor(void *, void *); 515static void pmap_pdp_dtor(void *, void *);
530#ifdef PAE 516#ifdef PAE
531/* need to allocate items of 4 pages */ 517/* need to allocate items of 4 pages */
532static void *pmap_pdp_alloc(struct pool *, int); 518static void *pmap_pdp_alloc(struct pool *, int);
533static void pmap_pdp_free(struct pool *, void *); 519static void pmap_pdp_free(struct pool *, void *);
534static struct pool_allocator pmap_pdp_allocator = { 520static struct pool_allocator pmap_pdp_allocator = {
@@ -1318,80 +1304,49 @@ pmap_bootstrap(vaddr_t kva_start) @@ -1318,80 +1304,49 @@ pmap_bootstrap(vaddr_t kva_start)
1318 /* 1304 /*
1319 * The TLB must be flushed after enabling large pages on Pentium 1305 * The TLB must be flushed after enabling large pages on Pentium
1320 * CPUs, according to section 3.6.2.2 of "Intel Architecture 1306 * CPUs, according to section 3.6.2.2 of "Intel Architecture
1321 * Software Developer's Manual, Volume 3: System Programming". 1307 * Software Developer's Manual, Volume 3: System Programming".
1322 */ 1308 */
1323 tlbflushg(); 1309 tlbflushg();
1324 1310
1325 /* Remap the kernel. */ 1311 /* Remap the kernel. */
1326 pmap_remap_largepages(); 1312 pmap_remap_largepages();
1327 } 1313 }
1328 pmap_init_lapic(); 1314 pmap_init_lapic();
1329#endif /* !XEN */ 1315#endif /* !XEN */
1330 1316
1331 
1332#ifdef __HAVE_DIRECT_MAP 1317#ifdef __HAVE_DIRECT_MAP
1333 pmap_init_directmap(kpm); 1318 pmap_init_directmap(kpm);
1334#else 1319#else
1335 if (VM_MIN_KERNEL_ADDRESS != KERNBASE) { 1320 pmap_vpage_cpualloc(&cpu_info_primary);
 1321
 1322 if (VM_MIN_KERNEL_ADDRESS == KERNBASE) { /* i386 */
 1323 early_zerop = (void *)cpu_info_primary.vpage[VPAGE_ZER];
 1324 early_zero_pte = cpu_info_primary.vpage_pte[VPAGE_ZER];
 1325 } else { /* amd64 */
1336 /* 1326 /*
1337 * zero_pte is stuck at the end of mapped space for the kernel 1327 * zero_pte is stuck at the end of mapped space for the kernel
1338 * image (disjunct from kva space). This is done so that it 1328 * image (disjunct from kva space). This is done so that it
1339 * can safely be used in pmap_growkernel (pmap_get_physpage), 1329 * can safely be used in pmap_growkernel (pmap_get_physpage),
1340 * when it's called for the first time. 1330 * when it's called for the first time.
1341 * XXXfvdl fix this for MULTIPROCESSOR later. 1331 * XXXfvdl fix this for MULTIPROCESSOR later.
1342 */ 1332 */
1343#ifdef XEN 1333#ifdef XEN
1344 /* early_zerop initialized in xen_locore() */ 1334 /* early_zerop initialized in xen_locore() */
1345#else 1335#else
1346 early_zerop = (void *)(KERNBASE + NKL2_KIMG_ENTRIES * NBPD_L2); 1336 early_zerop = (void *)(KERNBASE + NKL2_KIMG_ENTRIES * NBPD_L2);
1347#endif 1337#endif
1348 early_zero_pte = PTE_BASE + pl1_i((vaddr_t)early_zerop); 1338 early_zero_pte = PTE_BASE + pl1_i((vaddr_t)early_zerop);
1349 } 1339 }
1350 
1351 /* 
1352 * Now we allocate the "special" VAs which are used for tmp mappings 
1353 * by pmap. We allocate the VAs, and find the PTE that maps them via 
1354 * the linear PTE mapping. 
1355 */ 
1356 vaddr_t cpuva_base; 
1357 pt_entry_t *pte; 
1358 
1359#ifdef MULTIPROCESSOR 
1360 /* 
1361 * Waste some VA space to avoid false sharing of cache lines for page 
1362 * table pages: give each possible CPU a cache line of 8 PTEs to play 
1363 * with, though we only need 4. 
1364 */ 
1365 cpuva_base = pmap_bootstrap_valloc(maxcpus * NPTECL); 
1366#else 
1367 cpuva_base = pmap_bootstrap_valloc(4); 
1368#endif 
1369 pte = PTE_BASE + pl1_i(cpuva_base); 
1370 
1371 /* Values used to index the array */ 
1372 csrcp = (char *)cpuva_base; 
1373 csrc_pte = pte; 
1374 cdstp = (char *)cpuva_base + PAGE_SIZE; 
1375 cdst_pte = pte + 1; 
1376 zerop = (char *)cpuva_base + PAGE_SIZE * 2; 
1377 zero_pte = pte + 2; 
1378 ptpp = (char *)cpuva_base + PAGE_SIZE * 3; 
1379 ptp_pte = pte + 3; 
1380 
1381 if (VM_MIN_KERNEL_ADDRESS == KERNBASE) { 
1382 early_zerop = zerop; 
1383 early_zero_pte = zero_pte; 
1384 } 
1385#endif 1340#endif
1386 1341
1387#if defined(XEN) && defined(__x86_64__) 1342#if defined(XEN) && defined(__x86_64__)
1388 extern vaddr_t xen_dummy_page; 1343 extern vaddr_t xen_dummy_page;
1389 paddr_t xen_dummy_user_pgd; 1344 paddr_t xen_dummy_user_pgd;
1390 1345
1391 /* 1346 /*
1392 * We want a dummy page directory for Xen: when deactivating a pmap, 1347 * We want a dummy page directory for Xen: when deactivating a pmap,
1393 * Xen will still consider it active. So we set user PGD to this one 1348 * Xen will still consider it active. So we set user PGD to this one
1394 * to lift all protection on the now inactive page tables set. 1349 * to lift all protection on the now inactive page tables set.
1395 */ 1350 */
1396 xen_dummy_user_pgd = xen_dummy_page - KERNBASE; 1351 xen_dummy_user_pgd = xen_dummy_page - KERNBASE;
1397 1352
@@ -1705,26 +1660,77 @@ pmap_cpu_init_late(struct cpu_info *ci) @@ -1705,26 +1660,77 @@ pmap_cpu_init_late(struct cpu_info *ci)
1705 /* 1660 /*
1706 * The BP has already its own PD page allocated during early 1661 * The BP has already its own PD page allocated during early
1707 * MD startup. 1662 * MD startup.
1708 */ 1663 */
1709 if (ci == &cpu_info_primary) 1664 if (ci == &cpu_info_primary)
1710 return; 1665 return;
1711 1666
1712#ifdef PAE 1667#ifdef PAE
1713 cpu_alloc_l3_page(ci); 1668 cpu_alloc_l3_page(ci);
1714#endif 1669#endif
1715} 1670}
1716#endif 1671#endif
1717 1672
 1673#ifndef __HAVE_DIRECT_MAP
 1674CTASSERT(CACHE_LINE_SIZE > sizeof(pt_entry_t));
 1675CTASSERT(CACHE_LINE_SIZE % sizeof(pt_entry_t) == 0);
 1676
 1677static void
 1678pmap_vpage_cpualloc(struct cpu_info *ci)
 1679{
 1680 bool primary = (ci == &cpu_info_primary);
 1681 size_t i, npages;
 1682 vaddr_t vabase;
 1683 vsize_t vrange;
 1684
 1685 npages = (CACHE_LINE_SIZE / sizeof(pt_entry_t));
 1686 KASSERT(npages >= VPAGE_MAX);
 1687 vrange = npages * PAGE_SIZE;
 1688
 1689 if (primary) {
 1690 while ((vabase = pmap_bootstrap_valloc(1)) % vrange != 0) {
 1691 /* Waste some pages to align properly */
 1692 }
 1693 /* The base is aligned, allocate the rest (contiguous) */
 1694 pmap_bootstrap_valloc(npages - 1);
 1695 } else {
 1696 vabase = uvm_km_alloc(kernel_map, vrange, vrange,
 1697 UVM_KMF_VAONLY);
 1698 if (vabase == 0) {
 1699 panic("%s: failed to allocate tmp VA for CPU %d\n",
 1700 __func__, cpu_index(ci));
 1701 }
 1702 }
 1703
 1704 KASSERT((vaddr_t)&PTE_BASE[pl1_i(vabase)] % CACHE_LINE_SIZE == 0);
 1705
 1706 for (i = 0; i < VPAGE_MAX; i++) {
 1707 ci->vpage[i] = vabase + i * PAGE_SIZE;
 1708 ci->vpage_pte[i] = PTE_BASE + pl1_i(ci->vpage[i]);
 1709 }
 1710}
 1711
 1712void
 1713pmap_vpage_cpu_init(struct cpu_info *ci)
 1714{
 1715 if (ci == &cpu_info_primary) {
 1716 /* cpu0 already taken care of in pmap_bootstrap */
 1717 return;
 1718 }
 1719
 1720 pmap_vpage_cpualloc(ci);
 1721}
 1722#endif
 1723
1718/* 1724/*
1719 * p v _ e n t r y f u n c t i o n s 1725 * p v _ e n t r y f u n c t i o n s
1720 */ 1726 */
1721 1727
1722/* 1728/*
1723 * pmap_free_pvs: free a list of pv_entrys 1729 * pmap_free_pvs: free a list of pv_entrys
1724 */ 1730 */
1725 1731
1726static void 1732static void
1727pmap_free_pvs(struct pv_entry *pve) 1733pmap_free_pvs(struct pv_entry *pve)
1728{ 1734{
1729 struct pv_entry *next; 1735 struct pv_entry *next;
1730 1736
@@ -3029,91 +3035,92 @@ pmap_virtual_space(vaddr_t *startp, vadd @@ -3029,91 +3035,92 @@ pmap_virtual_space(vaddr_t *startp, vadd
3029 * pmap_zero_page: zero a page 3035 * pmap_zero_page: zero a page
3030 */ 3036 */
3031 3037
3032void 3038void
3033pmap_zero_page(paddr_t pa) 3039pmap_zero_page(paddr_t pa)
3034{ 3040{
3035#if defined(__HAVE_DIRECT_MAP) 3041#if defined(__HAVE_DIRECT_MAP)
3036 pagezero(PMAP_DIRECT_MAP(pa)); 3042 pagezero(PMAP_DIRECT_MAP(pa));
3037#else 3043#else
3038#if defined(XEN) 3044#if defined(XEN)
3039 if (XEN_VERSION_SUPPORTED(3, 4)) 3045 if (XEN_VERSION_SUPPORTED(3, 4))
3040 xen_pagezero(pa); 3046 xen_pagezero(pa);
3041#endif 3047#endif
 3048 struct cpu_info *ci;
3042 pt_entry_t *zpte; 3049 pt_entry_t *zpte;
3043 void *zerova; 3050 vaddr_t zerova;
3044 int id; 
3045 3051
3046 const pd_entry_t pteflags = PG_V | PG_RW | pmap_pg_nx | PG_M | PG_U | 3052 const pd_entry_t pteflags = PG_V | PG_RW | pmap_pg_nx | PG_M | PG_U |
3047 PG_k; 3053 PG_k;
3048 3054
3049 kpreempt_disable(); 3055 kpreempt_disable();
3050 id = cpu_number(); 3056
3051 zpte = PTESLEW(zero_pte, id); 3057 ci = curcpu();
3052 zerova = VASLEW(zerop, id); 3058 zerova = ci->vpage[VPAGE_ZER];
 3059 zpte = ci->vpage_pte[VPAGE_ZER];
3053 3060
3054#ifdef DIAGNOSTIC 3061#ifdef DIAGNOSTIC
3055 if (*zpte) 3062 if (*zpte)
3056 panic("pmap_zero_page: lock botch"); 3063 panic("pmap_zero_page: lock botch");
3057#endif 3064#endif
3058 3065
3059 pmap_pte_set(zpte, pmap_pa2pte(pa) | pteflags); 3066 pmap_pte_set(zpte, pmap_pa2pte(pa) | pteflags);
3060 pmap_pte_flush(); 3067 pmap_pte_flush();
3061 pmap_update_pg((vaddr_t)zerova); /* flush TLB */ 3068 pmap_update_pg(zerova); /* flush TLB */
3062 3069
3063 memset(zerova, 0, PAGE_SIZE); 3070 memset((void *)zerova, 0, PAGE_SIZE);
3064 3071
3065#if defined(DIAGNOSTIC) || defined(XEN) 3072#if defined(DIAGNOSTIC) || defined(XEN)
3066 pmap_pte_set(zpte, 0); /* zap ! */ 3073 pmap_pte_set(zpte, 0); /* zap ! */
3067 pmap_pte_flush(); 3074 pmap_pte_flush();
3068#endif 3075#endif
3069 3076
3070 kpreempt_enable(); 3077 kpreempt_enable();
3071#endif /* defined(__HAVE_DIRECT_MAP) */ 3078#endif /* defined(__HAVE_DIRECT_MAP) */
3072} 3079}
3073 3080
3074/* 3081/*
3075 * pmap_pagezeroidle: the same, for the idle loop page zero'er. 3082 * pmap_pagezeroidle: the same, for the idle loop page zero'er.
3076 * Returns true if the page was zero'd, false if we aborted for 3083 * Returns true if the page was zero'd, false if we aborted for
3077 * some reason. 3084 * some reason.
3078 */ 3085 */
3079 3086
3080bool 3087bool
3081pmap_pageidlezero(paddr_t pa) 3088pmap_pageidlezero(paddr_t pa)
3082{ 3089{
3083#ifdef __HAVE_DIRECT_MAP 3090#ifdef __HAVE_DIRECT_MAP
3084 KASSERT(cpu_feature[0] & CPUID_SSE2); 3091 KASSERT(cpu_feature[0] & CPUID_SSE2);
3085 return sse2_idlezero_page((void *)PMAP_DIRECT_MAP(pa)); 3092 return sse2_idlezero_page((void *)PMAP_DIRECT_MAP(pa));
3086#else 3093#else
 3094 struct cpu_info *ci;
3087 pt_entry_t *zpte; 3095 pt_entry_t *zpte;
3088 void *zerova; 3096 vaddr_t zerova;
3089 bool rv; 3097 bool rv;
3090 int id; 
3091 3098
3092 const pd_entry_t pteflags = PG_V | PG_RW | pmap_pg_nx | PG_M | PG_U | 3099 const pd_entry_t pteflags = PG_V | PG_RW | pmap_pg_nx | PG_M | PG_U |
3093 PG_k; 3100 PG_k;
3094 3101
3095 id = cpu_number(); 3102 ci = curcpu();
3096 zpte = PTESLEW(zero_pte, id); 3103 zerova = ci->vpage[VPAGE_ZER];
3097 zerova = VASLEW(zerop, id); 3104 zpte = ci->vpage_pte[VPAGE_ZER];
3098 3105
3099 KASSERT(cpu_feature[0] & CPUID_SSE2); 3106 KASSERT(cpu_feature[0] & CPUID_SSE2);
3100 KASSERT(*zpte == 0); 3107 KASSERT(*zpte == 0);
3101 3108
3102 pmap_pte_set(zpte, pmap_pa2pte(pa) | pteflags); 3109 pmap_pte_set(zpte, pmap_pa2pte(pa) | pteflags);
3103 pmap_pte_flush(); 3110 pmap_pte_flush();
3104 pmap_update_pg((vaddr_t)zerova); /* flush TLB */ 3111 pmap_update_pg(zerova); /* flush TLB */
3105 3112
3106 rv = sse2_idlezero_page(zerova); 3113 rv = sse2_idlezero_page((void *)zerova);
3107 3114
3108#if defined(DIAGNOSTIC) || defined(XEN) 3115#if defined(DIAGNOSTIC) || defined(XEN)
3109 pmap_pte_set(zpte, 0); /* zap ! */ 3116 pmap_pte_set(zpte, 0); /* zap ! */
3110 pmap_pte_flush(); 3117 pmap_pte_flush();
3111#endif 3118#endif
3112 3119
3113 return rv; 3120 return rv;
3114#endif 3121#endif
3115} 3122}
3116 3123
3117/* 3124/*
3118 * pmap_copy_page: copy a page 3125 * pmap_copy_page: copy a page
3119 */ 3126 */
@@ -3123,101 +3130,104 @@ pmap_copy_page(paddr_t srcpa, paddr_t ds @@ -3123,101 +3130,104 @@ pmap_copy_page(paddr_t srcpa, paddr_t ds
3123{ 3130{
3124#if defined(__HAVE_DIRECT_MAP) 3131#if defined(__HAVE_DIRECT_MAP)
3125 vaddr_t srcva = PMAP_DIRECT_MAP(srcpa); 3132 vaddr_t srcva = PMAP_DIRECT_MAP(srcpa);
3126 vaddr_t dstva = PMAP_DIRECT_MAP(dstpa); 3133 vaddr_t dstva = PMAP_DIRECT_MAP(dstpa);
3127 3134
3128 memcpy((void *)dstva, (void *)srcva, PAGE_SIZE); 3135 memcpy((void *)dstva, (void *)srcva, PAGE_SIZE);
3129#else 3136#else
3130#if defined(XEN) 3137#if defined(XEN)
3131 if (XEN_VERSION_SUPPORTED(3, 4)) { 3138 if (XEN_VERSION_SUPPORTED(3, 4)) {
3132 xen_copy_page(srcpa, dstpa); 3139 xen_copy_page(srcpa, dstpa);
3133 return; 3140 return;
3134 } 3141 }
3135#endif 3142#endif
3136 pt_entry_t *spte; 3143 struct cpu_info *ci;
3137 pt_entry_t *dpte; 3144 pt_entry_t *srcpte, *dstpte;
3138 void *csrcva; 3145 vaddr_t srcva, dstva;
3139 void *cdstva; 
3140 int id; 
3141 3146
3142 const pd_entry_t pteflags = PG_V | PG_RW | pmap_pg_nx | PG_U | PG_k; 3147 const pd_entry_t pteflags = PG_V | PG_RW | pmap_pg_nx | PG_U | PG_k;
3143 3148
3144 kpreempt_disable(); 3149 kpreempt_disable();
3145 id = cpu_number(); 
3146 spte = PTESLEW(csrc_pte, id); 
3147 dpte = PTESLEW(cdst_pte, id); 
3148 csrcva = VASLEW(csrcp, id); 
3149 cdstva = VASLEW(cdstp, id); 
3150 3150
3151 KASSERT(*spte == 0 && *dpte == 0); 3151 ci = curcpu();
 3152 srcva = ci->vpage[VPAGE_SRC];
 3153 dstva = ci->vpage[VPAGE_DST];
 3154 srcpte = ci->vpage_pte[VPAGE_SRC];
 3155 dstpte = ci->vpage_pte[VPAGE_DST];
 3156
 3157 KASSERT(*srcpte == 0 && *dstpte == 0);
3152 3158
3153 pmap_pte_set(spte, pmap_pa2pte(srcpa) | pteflags); 3159 pmap_pte_set(srcpte, pmap_pa2pte(srcpa) | pteflags);
3154 pmap_pte_set(dpte, pmap_pa2pte(dstpa) | pteflags | PG_M); 3160 pmap_pte_set(dstpte, pmap_pa2pte(dstpa) | pteflags | PG_M);
3155 pmap_pte_flush(); 3161 pmap_pte_flush();
3156 pmap_update_2pg((vaddr_t)csrcva, (vaddr_t)cdstva); 3162 pmap_update_2pg(srcva, dstva);
3157 3163
3158 memcpy(cdstva, csrcva, PAGE_SIZE); 3164 memcpy((void *)dstva, (void *)srcva, PAGE_SIZE);
3159 3165
3160#if defined(DIAGNOSTIC) || defined(XEN) 3166#if defined(DIAGNOSTIC) || defined(XEN)
3161 pmap_pte_set(spte, 0); 3167 pmap_pte_set(srcpte, 0);
3162 pmap_pte_set(dpte, 0); 3168 pmap_pte_set(dstpte, 0);
3163 pmap_pte_flush(); 3169 pmap_pte_flush();
3164#endif 3170#endif
3165 3171
3166 kpreempt_enable(); 3172 kpreempt_enable();
3167#endif /* defined(__HAVE_DIRECT_MAP) */ 3173#endif /* defined(__HAVE_DIRECT_MAP) */
3168} 3174}
3169 3175
3170static pt_entry_t * 3176static pt_entry_t *
3171pmap_map_ptp(struct vm_page *ptp) 3177pmap_map_ptp(struct vm_page *ptp)
3172{ 3178{
3173#ifdef __HAVE_DIRECT_MAP 3179#ifdef __HAVE_DIRECT_MAP
3174 return (void *)PMAP_DIRECT_MAP(VM_PAGE_TO_PHYS(ptp)); 3180 return (void *)PMAP_DIRECT_MAP(VM_PAGE_TO_PHYS(ptp));
3175#else 3181#else
 3182 struct cpu_info *ci;
3176 pt_entry_t *ptppte; 3183 pt_entry_t *ptppte;
3177 void *ptpva; 3184 vaddr_t ptpva;
3178 int id; 
3179 3185
3180 KASSERT(kpreempt_disabled()); 3186 KASSERT(kpreempt_disabled());
3181 3187
3182#ifndef XEN 3188#ifndef XEN
3183 const pd_entry_t pteflags = PG_V | PG_RW | pmap_pg_nx | PG_U | PG_M | 3189 const pd_entry_t pteflags = PG_V | PG_RW | pmap_pg_nx | PG_U | PG_M |
3184 PG_k; 3190 PG_k;
3185#else 3191#else
3186 const pd_entry_t pteflags = PG_V | pmap_pg_nx | PG_U | PG_M | PG_k; 3192 const pd_entry_t pteflags = PG_V | pmap_pg_nx | PG_U | PG_M | PG_k;
3187#endif 3193#endif
3188 3194
3189 id = cpu_number(); 3195 ci = curcpu();
3190 ptppte = PTESLEW(ptp_pte, id); 3196 ptpva = ci->vpage[VPAGE_PTP];
3191 ptpva = VASLEW(ptpp, id); 3197 ptppte = ci->vpage_pte[VPAGE_PTP];
 3198
3192 pmap_pte_set(ptppte, pmap_pa2pte(VM_PAGE_TO_PHYS(ptp)) | pteflags); 3199 pmap_pte_set(ptppte, pmap_pa2pte(VM_PAGE_TO_PHYS(ptp)) | pteflags);
3193 3200
3194 pmap_pte_flush(); 3201 pmap_pte_flush();
3195 pmap_update_pg((vaddr_t)ptpva); 3202 pmap_update_pg(ptpva);
3196 3203
3197 return (pt_entry_t *)ptpva; 3204 return (pt_entry_t *)ptpva;
3198#endif 3205#endif
3199} 3206}
3200 3207
3201static void 3208static void
3202pmap_unmap_ptp(void) 3209pmap_unmap_ptp(void)
3203{ 3210{
3204#ifndef __HAVE_DIRECT_MAP 3211#ifndef __HAVE_DIRECT_MAP
3205#if defined(DIAGNOSTIC) || defined(XEN) 3212#if defined(DIAGNOSTIC) || defined(XEN)
 3213 struct cpu_info *ci;
3206 pt_entry_t *pte; 3214 pt_entry_t *pte;
3207 3215
3208 KASSERT(kpreempt_disabled()); 3216 KASSERT(kpreempt_disabled());
3209 3217
3210 pte = PTESLEW(ptp_pte, cpu_number()); 3218 ci = curcpu();
 3219 pte = ci->vpage_pte[VPAGE_PTP];
 3220
3211 if (*pte != 0) { 3221 if (*pte != 0) {
3212 pmap_pte_set(pte, 0); 3222 pmap_pte_set(pte, 0);
3213 pmap_pte_flush(); 3223 pmap_pte_flush();
3214 } 3224 }
3215#endif 3225#endif
3216#endif 3226#endif
3217} 3227}
3218 3228
3219static pt_entry_t * 3229static pt_entry_t *
3220pmap_map_pte(struct pmap *pmap, struct vm_page *ptp, vaddr_t va) 3230pmap_map_pte(struct pmap *pmap, struct vm_page *ptp, vaddr_t va)
3221{ 3231{
3222 3232
3223 KASSERT(kpreempt_disabled()); 3233 KASSERT(kpreempt_disabled());

cvs diff -r1.108 -r1.109 src/sys/arch/xen/x86/cpu.c (expand / switch to unified diff)

--- src/sys/arch/xen/x86/cpu.c 2017/02/05 10:42:21 1.108
+++ src/sys/arch/xen/x86/cpu.c 2017/02/11 14:11:24 1.109
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: cpu.c,v 1.108 2017/02/05 10:42:21 maxv Exp $ */ 1/* $NetBSD: cpu.c,v 1.109 2017/02/11 14:11:24 maxv Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2000 The NetBSD Foundation, Inc. 4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 * Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi, 5 * Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi,
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * This code is derived from software contributed to The NetBSD Foundation 8 * This code is derived from software contributed to The NetBSD Foundation
9 * by RedBack Networks Inc. 9 * by RedBack Networks Inc.
10 * 10 *
11 * Author: Bill Sommerfeld 11 * Author: Bill Sommerfeld
12 * 12 *
13 * Redistribution and use in source and binary forms, with or without 13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions 14 * modification, are permitted provided that the following conditions
@@ -55,27 +55,27 @@ @@ -55,27 +55,27 @@
55 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 55 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE 57 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE
58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64 * SUCH DAMAGE. 64 * SUCH DAMAGE.
65 */ 65 */
66 66
67#include <sys/cdefs.h> 67#include <sys/cdefs.h>
68__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.108 2017/02/05 10:42:21 maxv Exp $"); 68__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.109 2017/02/11 14:11:24 maxv Exp $");
69 69
70#include "opt_ddb.h" 70#include "opt_ddb.h"
71#include "opt_multiprocessor.h" 71#include "opt_multiprocessor.h"
72#include "opt_mpbios.h" /* for MPDEBUG */ 72#include "opt_mpbios.h" /* for MPDEBUG */
73#include "opt_mtrr.h" 73#include "opt_mtrr.h"
74#include "opt_xen.h" 74#include "opt_xen.h"
75 75
76#include "lapic.h" 76#include "lapic.h"
77#include "ioapic.h" 77#include "ioapic.h"
78 78
79#include <sys/param.h> 79#include <sys/param.h>
80#include <sys/proc.h> 80#include <sys/proc.h>
81#include <sys/systm.h> 81#include <sys/systm.h>
@@ -349,26 +349,29 @@ cpu_vm_init(struct cpu_info *ci) @@ -349,26 +349,29 @@ cpu_vm_init(struct cpu_info *ci)
349 default: 349 default:
350 tcolors /= cai->cai_associativity; 350 tcolors /= cai->cai_associativity;
351 } 351 }
352 ncolors = max(ncolors, tcolors); 352 ncolors = max(ncolors, tcolors);
353 } 353 }
354 354
355 /* 355 /*
356 * Knowing the size of the largest cache on this CPU, potentially 356 * Knowing the size of the largest cache on this CPU, potentially
357 * re-color our pages. 357 * re-color our pages.
358 */ 358 */
359 aprint_debug_dev(ci->ci_dev, "%d page colors\n", ncolors); 359 aprint_debug_dev(ci->ci_dev, "%d page colors\n", ncolors);
360 uvm_page_recolor(ncolors); 360 uvm_page_recolor(ncolors);
361 pmap_tlb_cpu_init(ci); 361 pmap_tlb_cpu_init(ci);
 362#ifndef __HAVE_DIRECT_MAP
 363 pmap_vpage_cpu_init(ci);
 364#endif
362} 365}
363 366
364static void 367static void
365cpu_attach_common(device_t parent, device_t self, void *aux) 368cpu_attach_common(device_t parent, device_t self, void *aux)
366{ 369{
367 struct cpu_softc *sc = device_private(self); 370 struct cpu_softc *sc = device_private(self);
368 struct cpu_attach_args *caa = aux; 371 struct cpu_attach_args *caa = aux;
369 struct cpu_info *ci; 372 struct cpu_info *ci;
370 uintptr_t ptr; 373 uintptr_t ptr;
371 int cpunum = caa->cpu_number; 374 int cpunum = caa->cpu_number;
372 static bool again = false; 375 static bool again = false;
373 376
374 sc->sc_dev = self; 377 sc->sc_dev = self;