Sat May 29 21:54:51 2021 UTC ()
Rename pmap_asn_info to pmap_percpu, and pmap::pm_asni to pmap::pm_percpu.
No functional change.


(thorpej)
diff -r1.278 -r1.279 src/sys/arch/alpha/alpha/pmap.c
diff -r1.85 -r1.86 src/sys/arch/alpha/include/pmap.h

cvs diff -r1.278 -r1.279 src/sys/arch/alpha/alpha/pmap.c (switch to unified diff)

--- src/sys/arch/alpha/alpha/pmap.c 2021/05/24 03:43:24 1.278
+++ src/sys/arch/alpha/alpha/pmap.c 2021/05/29 21:54:50 1.279
@@ -1,2583 +1,2583 @@ @@ -1,2583 +1,2583 @@
1/* $NetBSD: pmap.c,v 1.278 2021/05/24 03:43:24 thorpej Exp $ */ 1/* $NetBSD: pmap.c,v 1.279 2021/05/29 21:54:50 thorpej Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1998, 1999, 2000, 2001, 2007, 2008, 2020 4 * Copyright (c) 1998, 1999, 2000, 2001, 2007, 2008, 2020
5 * The NetBSD Foundation, Inc. 5 * The NetBSD Foundation, Inc.
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 Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
10 * NASA Ames Research Center, by Andrew Doran and Mindaugas Rasiukevicius, 10 * NASA Ames Research Center, by Andrew Doran and Mindaugas Rasiukevicius,
11 * and by Chris G. Demetriou. 11 * and by Chris G. Demetriou.
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
15 * are met: 15 * are met:
16 * 1. Redistributions of source code must retain the above copyright 16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer. 17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright 18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the 19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution. 20 * documentation and/or other materials provided with the distribution.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE. 32 * POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35/* 35/*
36 * Copyright (c) 1991, 1993 36 * Copyright (c) 1991, 1993
37 * The Regents of the University of California. All rights reserved. 37 * The Regents of the University of California. All rights reserved.
38 * 38 *
39 * This code is derived from software contributed to Berkeley by 39 * This code is derived from software contributed to Berkeley by
40 * the Systems Programming Group of the University of Utah Computer 40 * the Systems Programming Group of the University of Utah Computer
41 * Science Department. 41 * Science Department.
42 * 42 *
43 * Redistribution and use in source and binary forms, with or without 43 * Redistribution and use in source and binary forms, with or without
44 * modification, are permitted provided that the following conditions 44 * modification, are permitted provided that the following conditions
45 * are met: 45 * are met:
46 * 1. Redistributions of source code must retain the above copyright 46 * 1. Redistributions of source code must retain the above copyright
47 * notice, this list of conditions and the following disclaimer. 47 * notice, this list of conditions and the following disclaimer.
48 * 2. Redistributions in binary form must reproduce the above copyright 48 * 2. Redistributions in binary form must reproduce the above copyright
49 * notice, this list of conditions and the following disclaimer in the 49 * notice, this list of conditions and the following disclaimer in the
50 * documentation and/or other materials provided with the distribution. 50 * documentation and/or other materials provided with the distribution.
51 * 3. Neither the name of the University nor the names of its contributors 51 * 3. Neither the name of the University nor the names of its contributors
52 * may be used to endorse or promote products derived from this software 52 * may be used to endorse or promote products derived from this software
53 * without specific prior written permission. 53 * without specific prior written permission.
54 * 54 *
55 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 55 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
56 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 56 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
58 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 58 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
59 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 59 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
60 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 60 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
61 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 61 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
62 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 62 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
63 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 63 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
64 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 64 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65 * SUCH DAMAGE. 65 * SUCH DAMAGE.
66 * 66 *
67 * @(#)pmap.c 8.6 (Berkeley) 5/27/94 67 * @(#)pmap.c 8.6 (Berkeley) 5/27/94
68 */ 68 */
69 69
70/* 70/*
71 * DEC Alpha physical map management code. 71 * DEC Alpha physical map management code.
72 * 72 *
73 * History: 73 * History:
74 * 74 *
75 * This pmap started life as a Motorola 68851/68030 pmap, 75 * This pmap started life as a Motorola 68851/68030 pmap,
76 * written by Mike Hibler at the University of Utah. 76 * written by Mike Hibler at the University of Utah.
77 * 77 *
78 * It was modified for the DEC Alpha by Chris Demetriou 78 * It was modified for the DEC Alpha by Chris Demetriou
79 * at Carnegie Mellon University. 79 * at Carnegie Mellon University.
80 * 80 *
81 * Support for non-contiguous physical memory was added by 81 * Support for non-contiguous physical memory was added by
82 * Jason R. Thorpe of the Numerical Aerospace Simulation 82 * Jason R. Thorpe of the Numerical Aerospace Simulation
83 * Facility, NASA Ames Research Center and Chris Demetriou. 83 * Facility, NASA Ames Research Center and Chris Demetriou.
84 * 84 *
85 * Page table management and a major cleanup were undertaken 85 * Page table management and a major cleanup were undertaken
86 * by Jason R. Thorpe, with lots of help from Ross Harvey of 86 * by Jason R. Thorpe, with lots of help from Ross Harvey of
87 * Avalon Computer Systems and from Chris Demetriou. 87 * Avalon Computer Systems and from Chris Demetriou.
88 * 88 *
89 * Support for the new UVM pmap interface was written by 89 * Support for the new UVM pmap interface was written by
90 * Jason R. Thorpe. 90 * Jason R. Thorpe.
91 * 91 *
92 * Support for ASNs was written by Jason R. Thorpe, again 92 * Support for ASNs was written by Jason R. Thorpe, again
93 * with help from Chris Demetriou and Ross Harvey. 93 * with help from Chris Demetriou and Ross Harvey.
94 * 94 *
95 * The locking protocol was written by Jason R. Thorpe, 95 * The locking protocol was written by Jason R. Thorpe,
96 * using Chuck Cranor's i386 pmap for UVM as a model. 96 * using Chuck Cranor's i386 pmap for UVM as a model.
97 * 97 *
98 * TLB shootdown code was written (and then subsequently 98 * TLB shootdown code was written (and then subsequently
99 * rewritten some years later, borrowing some ideas from 99 * rewritten some years later, borrowing some ideas from
100 * the x86 pmap) by Jason R. Thorpe. 100 * the x86 pmap) by Jason R. Thorpe.
101 * 101 *
102 * Multiprocessor modifications by Andrew Doran and 102 * Multiprocessor modifications by Andrew Doran and
103 * Jason R. Thorpe. 103 * Jason R. Thorpe.
104 * 104 *
105 * Notes: 105 * Notes:
106 * 106 *
107 * All user page table access is done via K0SEG. Kernel 107 * All user page table access is done via K0SEG. Kernel
108 * page table access is done via the recursive Virtual Page 108 * page table access is done via the recursive Virtual Page
109 * Table becase kernel PT pages are pre-allocated and never 109 * Table becase kernel PT pages are pre-allocated and never
110 * freed, so no VPT fault handling is requiried. 110 * freed, so no VPT fault handling is requiried.
111 */ 111 */
112 112
113/* 113/*
114 * Manages physical address maps. 114 * Manages physical address maps.
115 * 115 *
116 * Since the information managed by this module is 116 * Since the information managed by this module is
117 * also stored by the logical address mapping module, 117 * also stored by the logical address mapping module,
118 * this module may throw away valid virtual-to-physical 118 * this module may throw away valid virtual-to-physical
119 * mappings at almost any time. However, invalidations 119 * mappings at almost any time. However, invalidations
120 * of virtual-to-physical mappings must be done as 120 * of virtual-to-physical mappings must be done as
121 * requested. 121 * requested.
122 * 122 *
123 * In order to cope with hardware architectures which 123 * In order to cope with hardware architectures which
124 * make virtual-to-physical map invalidates expensive, 124 * make virtual-to-physical map invalidates expensive,
125 * this module may delay invalidate or reduced protection 125 * this module may delay invalidate or reduced protection
126 * operations until such time as they are actually 126 * operations until such time as they are actually
127 * necessary. This module is given full information as 127 * necessary. This module is given full information as
128 * to which processors are currently using which maps, 128 * to which processors are currently using which maps,
129 * and to when physical maps must be made correct. 129 * and to when physical maps must be made correct.
130 */ 130 */
131 131
132#include "opt_lockdebug.h" 132#include "opt_lockdebug.h"
133#include "opt_sysv.h" 133#include "opt_sysv.h"
134#include "opt_multiprocessor.h" 134#include "opt_multiprocessor.h"
135 135
136#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 136#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
137 137
138__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.278 2021/05/24 03:43:24 thorpej Exp $"); 138__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.279 2021/05/29 21:54:50 thorpej Exp $");
139 139
140#include <sys/param.h> 140#include <sys/param.h>
141#include <sys/systm.h> 141#include <sys/systm.h>
142#include <sys/kernel.h> 142#include <sys/kernel.h>
143#include <sys/proc.h> 143#include <sys/proc.h>
144#include <sys/malloc.h> 144#include <sys/malloc.h>
145#include <sys/pool.h> 145#include <sys/pool.h>
146#include <sys/buf.h> 146#include <sys/buf.h>
147#include <sys/evcnt.h> 147#include <sys/evcnt.h>
148#include <sys/atomic.h> 148#include <sys/atomic.h>
149#include <sys/cpu.h> 149#include <sys/cpu.h>
150 150
151#include <uvm/uvm.h> 151#include <uvm/uvm.h>
152 152
153#if defined(MULTIPROCESSOR) 153#if defined(MULTIPROCESSOR)
154#include <machine/rpb.h> 154#include <machine/rpb.h>
155#endif 155#endif
156 156
157#ifdef DEBUG 157#ifdef DEBUG
158#define PDB_FOLLOW 0x0001 158#define PDB_FOLLOW 0x0001
159#define PDB_INIT 0x0002 159#define PDB_INIT 0x0002
160#define PDB_ENTER 0x0004 160#define PDB_ENTER 0x0004
161#define PDB_REMOVE 0x0008 161#define PDB_REMOVE 0x0008
162#define PDB_CREATE 0x0010 162#define PDB_CREATE 0x0010
163#define PDB_PTPAGE 0x0020 163#define PDB_PTPAGE 0x0020
164#define PDB_ASN 0x0040 164#define PDB_ASN 0x0040
165#define PDB_BITS 0x0080 165#define PDB_BITS 0x0080
166#define PDB_COLLECT 0x0100 166#define PDB_COLLECT 0x0100
167#define PDB_PROTECT 0x0200 167#define PDB_PROTECT 0x0200
168#define PDB_BOOTSTRAP 0x1000 168#define PDB_BOOTSTRAP 0x1000
169#define PDB_PARANOIA 0x2000 169#define PDB_PARANOIA 0x2000
170#define PDB_WIRING 0x4000 170#define PDB_WIRING 0x4000
171#define PDB_PVDUMP 0x8000 171#define PDB_PVDUMP 0x8000
172 172
173int debugmap = 0; 173int debugmap = 0;
174int pmapdebug = PDB_PARANOIA; 174int pmapdebug = PDB_PARANOIA;
175#endif 175#endif
176 176
177#if defined(MULTIPROCESSOR) 177#if defined(MULTIPROCESSOR)
178#define PMAP_MP(x) x 178#define PMAP_MP(x) x
179#else 179#else
180#define PMAP_MP(x) __nothing 180#define PMAP_MP(x) __nothing
181#endif /* MULTIPROCESSOR */ 181#endif /* MULTIPROCESSOR */
182 182
183/* 183/*
184 * Given a map and a machine independent protection code, 184 * Given a map and a machine independent protection code,
185 * convert to an alpha protection code. 185 * convert to an alpha protection code.
186 */ 186 */
187#define pte_prot(m, p) (protection_codes[m == pmap_kernel() ? 0 : 1][p]) 187#define pte_prot(m, p) (protection_codes[m == pmap_kernel() ? 0 : 1][p])
188static int protection_codes[2][8] __read_mostly; 188static int protection_codes[2][8] __read_mostly;
189 189
190/* 190/*
191 * kernel_lev1map: 191 * kernel_lev1map:
192 * 192 *
193 * Kernel level 1 page table. This maps all kernel level 2 193 * Kernel level 1 page table. This maps all kernel level 2
194 * page table pages, and is used as a template for all user 194 * page table pages, and is used as a template for all user
195 * pmap level 1 page tables. When a new user level 1 page 195 * pmap level 1 page tables. When a new user level 1 page
196 * table is allocated, all kernel_lev1map PTEs for kernel 196 * table is allocated, all kernel_lev1map PTEs for kernel
197 * addresses are copied to the new map. 197 * addresses are copied to the new map.
198 * 198 *
199 * The kernel also has an initial set of kernel level 2 page 199 * The kernel also has an initial set of kernel level 2 page
200 * table pages. These map the kernel level 3 page table pages. 200 * table pages. These map the kernel level 3 page table pages.
201 * As kernel level 3 page table pages are added, more level 2 201 * As kernel level 3 page table pages are added, more level 2
202 * page table pages may be added to map them. These pages are 202 * page table pages may be added to map them. These pages are
203 * never freed. 203 * never freed.
204 * 204 *
205 * Finally, the kernel also has an initial set of kernel level 205 * Finally, the kernel also has an initial set of kernel level
206 * 3 page table pages. These map pages in K1SEG. More level 206 * 3 page table pages. These map pages in K1SEG. More level
207 * 3 page table pages may be added at run-time if additional 207 * 3 page table pages may be added at run-time if additional
208 * K1SEG address space is required. These pages are never freed. 208 * K1SEG address space is required. These pages are never freed.
209 * 209 *
210 * NOTE: When mappings are inserted into the kernel pmap, all 210 * NOTE: When mappings are inserted into the kernel pmap, all
211 * level 2 and level 3 page table pages must already be allocated 211 * level 2 and level 3 page table pages must already be allocated
212 * and mapped into the parent page table. 212 * and mapped into the parent page table.
213 */ 213 */
214pt_entry_t *kernel_lev1map __read_mostly; 214pt_entry_t *kernel_lev1map __read_mostly;
215 215
216/* 216/*
217 * Virtual Page Table. 217 * Virtual Page Table.
218 */ 218 */
219static pt_entry_t *VPT __read_mostly; 219static pt_entry_t *VPT __read_mostly;
220 220
221static struct { 221static struct {
222 struct pmap k_pmap; 222 struct pmap k_pmap;
223} kernel_pmap_store __cacheline_aligned; 223} kernel_pmap_store __cacheline_aligned;
224 224
225struct pmap *const kernel_pmap_ptr = &kernel_pmap_store.k_pmap; 225struct pmap *const kernel_pmap_ptr = &kernel_pmap_store.k_pmap;
226 226
227/* PA of first available physical page */ 227/* PA of first available physical page */
228paddr_t avail_start __read_mostly; 228paddr_t avail_start __read_mostly;
229 229
230/* PA of last available physical page */ 230/* PA of last available physical page */
231paddr_t avail_end __read_mostly; 231paddr_t avail_end __read_mostly;
232 232
233/* VA of last avail page (end of kernel AS) */ 233/* VA of last avail page (end of kernel AS) */
234static vaddr_t virtual_end __read_mostly; 234static vaddr_t virtual_end __read_mostly;
235 235
236/* Has pmap_init completed? */ 236/* Has pmap_init completed? */
237static bool pmap_initialized __read_mostly; 237static bool pmap_initialized __read_mostly;
238 238
239/* Instrumentation */ 239/* Instrumentation */
240u_long pmap_pages_stolen __read_mostly; 240u_long pmap_pages_stolen __read_mostly;
241 241
242/* 242/*
243 * This variable contains the number of CPU IDs we need to allocate 243 * This variable contains the number of CPU IDs we need to allocate
244 * space for when allocating the pmap structure. It is used to 244 * space for when allocating the pmap structure. It is used to
245 * size a per-CPU array of ASN and ASN Generation number. 245 * size a per-CPU array of ASN and ASN Generation number.
246 */ 246 */
247static u_long pmap_ncpuids __read_mostly; 247static u_long pmap_ncpuids __read_mostly;
248 248
249#ifndef PMAP_PV_LOWAT 249#ifndef PMAP_PV_LOWAT
250#define PMAP_PV_LOWAT 16 250#define PMAP_PV_LOWAT 16
251#endif 251#endif
252int pmap_pv_lowat __read_mostly = PMAP_PV_LOWAT; 252int pmap_pv_lowat __read_mostly = PMAP_PV_LOWAT;
253 253
254/* 254/*
255 * List of all pmaps, used to update them when e.g. additional kernel 255 * List of all pmaps, used to update them when e.g. additional kernel
256 * page tables are allocated. This list is kept LRU-ordered by 256 * page tables are allocated. This list is kept LRU-ordered by
257 * pmap_activate(). 257 * pmap_activate().
258 */ 258 */
259static TAILQ_HEAD(, pmap) pmap_all_pmaps __cacheline_aligned; 259static TAILQ_HEAD(, pmap) pmap_all_pmaps __cacheline_aligned;
260 260
261/* 261/*
262 * The pools from which pmap structures and sub-structures are allocated. 262 * The pools from which pmap structures and sub-structures are allocated.
263 */ 263 */
264static struct pool_cache pmap_pmap_cache __read_mostly; 264static struct pool_cache pmap_pmap_cache __read_mostly;
265static struct pool_cache pmap_l1pt_cache __read_mostly; 265static struct pool_cache pmap_l1pt_cache __read_mostly;
266static struct pool_cache pmap_pv_cache __read_mostly; 266static struct pool_cache pmap_pv_cache __read_mostly;
267 267
268CTASSERT(offsetof(struct pmap, pm_asni[0]) == COHERENCY_UNIT); 268CTASSERT(offsetof(struct pmap, pm_percpu[0]) == COHERENCY_UNIT);
269CTASSERT(PMAP_SIZEOF(ALPHA_MAXPROCS) < ALPHA_PGBYTES); 269CTASSERT(PMAP_SIZEOF(ALPHA_MAXPROCS) < ALPHA_PGBYTES);
270CTASSERT(sizeof(struct pmap_asn_info) == COHERENCY_UNIT); 270CTASSERT(sizeof(struct pmap_percpu) == COHERENCY_UNIT);
271 271
272/* 272/*
273 * Address Space Numbers. 273 * Address Space Numbers.
274 * 274 *
275 * On many implementations of the Alpha architecture, the TLB entries and 275 * On many implementations of the Alpha architecture, the TLB entries and
276 * I-cache blocks are tagged with a unique number within an implementation- 276 * I-cache blocks are tagged with a unique number within an implementation-
277 * specified range. When a process context becomes active, the ASN is used 277 * specified range. When a process context becomes active, the ASN is used
278 * to match TLB entries; if a TLB entry for a particular VA does not match 278 * to match TLB entries; if a TLB entry for a particular VA does not match
279 * the current ASN, it is ignored (one could think of the processor as 279 * the current ASN, it is ignored (one could think of the processor as
280 * having a collection of <max ASN> separate TLBs). This allows operating 280 * having a collection of <max ASN> separate TLBs). This allows operating
281 * system software to skip the TLB flush that would otherwise be necessary 281 * system software to skip the TLB flush that would otherwise be necessary
282 * at context switch time. 282 * at context switch time.
283 * 283 *
284 * Alpha PTEs have a bit in them (PG_ASM - Address Space Match) that 284 * Alpha PTEs have a bit in them (PG_ASM - Address Space Match) that
285 * causes TLB entries to match any ASN. The PALcode also provides 285 * causes TLB entries to match any ASN. The PALcode also provides
286 * a TBI (Translation Buffer Invalidate) operation that flushes all 286 * a TBI (Translation Buffer Invalidate) operation that flushes all
287 * TLB entries that _do not_ have PG_ASM. We use this bit for kernel 287 * TLB entries that _do not_ have PG_ASM. We use this bit for kernel
288 * mappings, so that invalidation of all user mappings does not invalidate 288 * mappings, so that invalidation of all user mappings does not invalidate
289 * kernel mappings (which are consistent across all processes). 289 * kernel mappings (which are consistent across all processes).
290 * 290 *
291 * pmap_next_asn always indicates to the next ASN to use. When 291 * pmap_next_asn always indicates to the next ASN to use. When
292 * pmap_next_asn exceeds pmap_max_asn, we start a new ASN generation. 292 * pmap_next_asn exceeds pmap_max_asn, we start a new ASN generation.
293 * 293 *
294 * When a new ASN generation is created, the per-process (i.e. non-PG_ASM) 294 * When a new ASN generation is created, the per-process (i.e. non-PG_ASM)
295 * TLB entries and the I-cache are flushed, the generation number is bumped, 295 * TLB entries and the I-cache are flushed, the generation number is bumped,
296 * and pmap_next_asn is changed to indicate the first non-reserved ASN. 296 * and pmap_next_asn is changed to indicate the first non-reserved ASN.
297 * 297 *
298 * We reserve ASN #0 for pmaps that use the global kernel_lev1map. This 298 * We reserve ASN #0 for pmaps that use the global kernel_lev1map. This
299 * prevents the following scenario to ensure no accidental accesses to 299 * prevents the following scenario to ensure no accidental accesses to
300 * user space for LWPs using the kernel pmap. This is important because 300 * user space for LWPs using the kernel pmap. This is important because
301 * the PALcode may use the recursive VPT to service TLB misses. 301 * the PALcode may use the recursive VPT to service TLB misses.
302 * 302 *
303 * By reserving an ASN for the kernel, we are guaranteeing that an lwp 303 * By reserving an ASN for the kernel, we are guaranteeing that an lwp
304 * will not see any valid user space TLB entries until it passes through 304 * will not see any valid user space TLB entries until it passes through
305 * pmap_activate() for the first time. 305 * pmap_activate() for the first time.
306 * 306 *
307 * On processors that do not support ASNs, the PALcode invalidates 307 * On processors that do not support ASNs, the PALcode invalidates
308 * non-ASM TLB entries automatically on swpctx. We completely skip 308 * non-ASM TLB entries automatically on swpctx. We completely skip
309 * the ASN machinery in this case because the PALcode neither reads 309 * the ASN machinery in this case because the PALcode neither reads
310 * nor writes that field of the HWPCB. 310 * nor writes that field of the HWPCB.
311 */ 311 */
312 312
313/* max ASN supported by the system */ 313/* max ASN supported by the system */
314static u_int pmap_max_asn __read_mostly; 314static u_int pmap_max_asn __read_mostly;
315 315
316/* 316/*
317 * Locking: 317 * Locking:
318 * 318 *
319 * READ/WRITE LOCKS 319 * READ/WRITE LOCKS
320 * ---------------- 320 * ----------------
321 * 321 *
322 * * pmap_main_lock - This lock is used to prevent deadlock and/or 322 * * pmap_main_lock - This lock is used to prevent deadlock and/or
323 * provide mutex access to the pmap module. Most operations lock 323 * provide mutex access to the pmap module. Most operations lock
324 * the pmap first, then PV lists as needed. However, some operations, 324 * the pmap first, then PV lists as needed. However, some operations,
325 * such as pmap_page_protect(), lock the PV lists before locking 325 * such as pmap_page_protect(), lock the PV lists before locking
326 * the pmaps. To prevent deadlock, we require a mutex lock on the 326 * the pmaps. To prevent deadlock, we require a mutex lock on the
327 * pmap module if locking in the PV->pmap direction. This is 327 * pmap module if locking in the PV->pmap direction. This is
328 * implemented by acquiring a (shared) read lock on pmap_main_lock 328 * implemented by acquiring a (shared) read lock on pmap_main_lock
329 * if locking pmap->PV and a (exclusive) write lock if locking in 329 * if locking pmap->PV and a (exclusive) write lock if locking in
330 * the PV->pmap direction. Since only one thread can hold a write 330 * the PV->pmap direction. Since only one thread can hold a write
331 * lock at a time, this provides the mutex. 331 * lock at a time, this provides the mutex.
332 * 332 *
333 * MUTEXES 333 * MUTEXES
334 * ------- 334 * -------
335 * 335 *
336 * * pmap lock (global hash) - These locks protect the pmap structures. 336 * * pmap lock (global hash) - These locks protect the pmap structures.
337 * 337 *
338 * * pmap activation lock (global hash) - These IPL_SCHED spin locks 338 * * pmap activation lock (global hash) - These IPL_SCHED spin locks
339 * synchronize pmap_activate() and TLB shootdowns. This has a lock 339 * synchronize pmap_activate() and TLB shootdowns. This has a lock
340 * ordering constraint with the tlb_lock: 340 * ordering constraint with the tlb_lock:
341 * 341 *
342 * tlb_lock -> pmap activation lock 342 * tlb_lock -> pmap activation lock
343 * 343 *
344 * * pvh_lock (global hash) - These locks protect the PV lists for 344 * * pvh_lock (global hash) - These locks protect the PV lists for
345 * managed pages. 345 * managed pages.
346 * 346 *
347 * * tlb_lock - This IPL_VM lock serializes local and remote TLB 347 * * tlb_lock - This IPL_VM lock serializes local and remote TLB
348 * invalidation. 348 * invalidation.
349 * 349 *
350 * * pmap_all_pmaps_lock - This lock protects the global list of 350 * * pmap_all_pmaps_lock - This lock protects the global list of
351 * all pmaps. 351 * all pmaps.
352 * 352 *
353 * * pmap_growkernel_lock - This lock protects pmap_growkernel() 353 * * pmap_growkernel_lock - This lock protects pmap_growkernel()
354 * and the virtual_end variable. 354 * and the virtual_end variable.
355 * 355 *
356 * There is a lock ordering constraint for pmap_growkernel_lock. 356 * There is a lock ordering constraint for pmap_growkernel_lock.
357 * pmap_growkernel() acquires the locks in the following order: 357 * pmap_growkernel() acquires the locks in the following order:
358 * 358 *
359 * pmap_growkernel_lock (write) -> pmap_all_pmaps_lock -> 359 * pmap_growkernel_lock (write) -> pmap_all_pmaps_lock ->
360 * pmap lock 360 * pmap lock
361 * 361 *
362 * We need to ensure consistency between user pmaps and the 362 * We need to ensure consistency between user pmaps and the
363 * kernel_lev1map. For this reason, pmap_growkernel_lock must 363 * kernel_lev1map. For this reason, pmap_growkernel_lock must
364 * be held to prevent kernel_lev1map changing across pmaps 364 * be held to prevent kernel_lev1map changing across pmaps
365 * being added to / removed from the global pmaps list. 365 * being added to / removed from the global pmaps list.
366 * 366 *
367 * Address space number management (global ASN counters and per-pmap 367 * Address space number management (global ASN counters and per-pmap
368 * ASN state) are not locked; they use arrays of values indexed 368 * ASN state) are not locked; they use arrays of values indexed
369 * per-processor. 369 * per-processor.
370 * 370 *
371 * All internal functions which operate on a pmap are called 371 * All internal functions which operate on a pmap are called
372 * with the pmap already locked by the caller (which will be 372 * with the pmap already locked by the caller (which will be
373 * an interface function). 373 * an interface function).
374 */ 374 */
375static krwlock_t pmap_main_lock __cacheline_aligned; 375static krwlock_t pmap_main_lock __cacheline_aligned;
376static kmutex_t pmap_all_pmaps_lock __cacheline_aligned; 376static kmutex_t pmap_all_pmaps_lock __cacheline_aligned;
377static krwlock_t pmap_growkernel_lock __cacheline_aligned; 377static krwlock_t pmap_growkernel_lock __cacheline_aligned;
378 378
379#define PMAP_MAP_TO_HEAD_LOCK() rw_enter(&pmap_main_lock, RW_READER) 379#define PMAP_MAP_TO_HEAD_LOCK() rw_enter(&pmap_main_lock, RW_READER)
380#define PMAP_MAP_TO_HEAD_UNLOCK() rw_exit(&pmap_main_lock) 380#define PMAP_MAP_TO_HEAD_UNLOCK() rw_exit(&pmap_main_lock)
381#define PMAP_HEAD_TO_MAP_LOCK() rw_enter(&pmap_main_lock, RW_WRITER) 381#define PMAP_HEAD_TO_MAP_LOCK() rw_enter(&pmap_main_lock, RW_WRITER)
382#define PMAP_HEAD_TO_MAP_UNLOCK() rw_exit(&pmap_main_lock) 382#define PMAP_HEAD_TO_MAP_UNLOCK() rw_exit(&pmap_main_lock)
383 383
384static union { 384static union {
385 kmutex_t lock; 385 kmutex_t lock;
386 uint8_t pad[COHERENCY_UNIT]; 386 uint8_t pad[COHERENCY_UNIT];
387} pmap_pvh_locks[64] __cacheline_aligned; 387} pmap_pvh_locks[64] __cacheline_aligned;
388 388
389#define PVH_LOCK_HASH(pg) \ 389#define PVH_LOCK_HASH(pg) \
390 ((((uintptr_t)(pg)) >> 6) & 63) 390 ((((uintptr_t)(pg)) >> 6) & 63)
391 391
392static inline kmutex_t * 392static inline kmutex_t *
393pmap_pvh_lock(struct vm_page *pg) 393pmap_pvh_lock(struct vm_page *pg)
394{ 394{
395 return &pmap_pvh_locks[PVH_LOCK_HASH(pg)].lock; 395 return &pmap_pvh_locks[PVH_LOCK_HASH(pg)].lock;
396} 396}
397 397
398static union { 398static union {
399 struct { 399 struct {
400 kmutex_t lock; 400 kmutex_t lock;
401 kmutex_t activation_lock; 401 kmutex_t activation_lock;
402 } locks; 402 } locks;
403 uint8_t pad[COHERENCY_UNIT]; 403 uint8_t pad[COHERENCY_UNIT];
404} pmap_pmap_locks[64] __cacheline_aligned; 404} pmap_pmap_locks[64] __cacheline_aligned;
405 405
406#define PMAP_LOCK_HASH(pm) \ 406#define PMAP_LOCK_HASH(pm) \
407 ((((uintptr_t)(pm)) >> 6) & 63) 407 ((((uintptr_t)(pm)) >> 6) & 63)
408 408
409static inline kmutex_t * 409static inline kmutex_t *
410pmap_pmap_lock(pmap_t const pmap) 410pmap_pmap_lock(pmap_t const pmap)
411{ 411{
412 return &pmap_pmap_locks[PMAP_LOCK_HASH(pmap)].locks.lock; 412 return &pmap_pmap_locks[PMAP_LOCK_HASH(pmap)].locks.lock;
413} 413}
414 414
415static inline kmutex_t * 415static inline kmutex_t *
416pmap_activation_lock(pmap_t const pmap) 416pmap_activation_lock(pmap_t const pmap)
417{ 417{
418 return &pmap_pmap_locks[PMAP_LOCK_HASH(pmap)].locks.activation_lock; 418 return &pmap_pmap_locks[PMAP_LOCK_HASH(pmap)].locks.activation_lock;
419} 419}
420 420
421#define PMAP_LOCK(pmap) mutex_enter(pmap_pmap_lock(pmap)) 421#define PMAP_LOCK(pmap) mutex_enter(pmap_pmap_lock(pmap))
422#define PMAP_UNLOCK(pmap) mutex_exit(pmap_pmap_lock(pmap)) 422#define PMAP_UNLOCK(pmap) mutex_exit(pmap_pmap_lock(pmap))
423 423
424#define PMAP_ACT_LOCK(pmap) mutex_spin_enter(pmap_activation_lock(pmap)) 424#define PMAP_ACT_LOCK(pmap) mutex_spin_enter(pmap_activation_lock(pmap))
425#define PMAP_ACT_TRYLOCK(pmap) mutex_tryenter(pmap_activation_lock(pmap)) 425#define PMAP_ACT_TRYLOCK(pmap) mutex_tryenter(pmap_activation_lock(pmap))
426#define PMAP_ACT_UNLOCK(pmap) mutex_spin_exit(pmap_activation_lock(pmap)) 426#define PMAP_ACT_UNLOCK(pmap) mutex_spin_exit(pmap_activation_lock(pmap))
427 427
428#if defined(MULTIPROCESSOR) 428#if defined(MULTIPROCESSOR)
429#define pmap_all_cpus() cpus_running 429#define pmap_all_cpus() cpus_running
430#else 430#else
431#define pmap_all_cpus() ~0UL 431#define pmap_all_cpus() ~0UL
432#endif /* MULTIPROCESSOR */ 432#endif /* MULTIPROCESSOR */
433 433
434/* 434/*
435 * TLB management. 435 * TLB management.
436 * 436 *
437 * TLB invalidations need to be performed on local and remote CPUs 437 * TLB invalidations need to be performed on local and remote CPUs
438 * whenever parts of the PTE that the hardware or PALcode understands 438 * whenever parts of the PTE that the hardware or PALcode understands
439 * changes. In order amortize the cost of these operations, we will 439 * changes. In order amortize the cost of these operations, we will
440 * queue up to 8 addresses to invalidate in a batch. Any more than 440 * queue up to 8 addresses to invalidate in a batch. Any more than
441 * that, and we will hit the entire TLB. 441 * that, and we will hit the entire TLB.
442 * 442 *
443 * Some things that add complexity: 443 * Some things that add complexity:
444 * 444 *
445 * ==> ASNs. A CPU may have valid TLB entries for other than the current 445 * ==> ASNs. A CPU may have valid TLB entries for other than the current
446 * address spaace. We can only invalidate TLB entries for the current 446 * address spaace. We can only invalidate TLB entries for the current
447 * address space, so when asked to invalidate a VA for the non-current 447 * address space, so when asked to invalidate a VA for the non-current
448 * pmap on a given CPU, we simply invalidate the ASN for that pmap,CPU 448 * pmap on a given CPU, we simply invalidate the ASN for that pmap,CPU
449 * tuple so that new one is allocated on the next activation on that 449 * tuple so that new one is allocated on the next activation on that
450 * CPU. N.B. that for CPUs that don't implement ASNs, SWPCTX does all 450 * CPU. N.B. that for CPUs that don't implement ASNs, SWPCTX does all
451 * the work necessary, so we can skip some work in the pmap module 451 * the work necessary, so we can skip some work in the pmap module
452 * itself. 452 * itself.
453 * 453 *
454 * When a pmap is activated on a given CPU, we set a corresponding 454 * When a pmap is activated on a given CPU, we set a corresponding
455 * bit in pmap::pm_cpus, indicating that it potentially has valid 455 * bit in pmap::pm_cpus, indicating that it potentially has valid
456 * TLB entries for that address space. This bitmap is then used to 456 * TLB entries for that address space. This bitmap is then used to
457 * determine which remote CPUs need to be notified of invalidations. 457 * determine which remote CPUs need to be notified of invalidations.
458 * The bit is cleared when the ASN is invalidated on that CPU. 458 * The bit is cleared when the ASN is invalidated on that CPU.
459 * 459 *
460 * In order to serialize with activating an address space on a 460 * In order to serialize with activating an address space on a
461 * given CPU (that we can reliably send notifications only to 461 * given CPU (that we can reliably send notifications only to
462 * relevant remote CPUs), we acquire the pmap lock in pmap_activate() 462 * relevant remote CPUs), we acquire the pmap lock in pmap_activate()
463 * and also hold the lock while remote shootdowns take place. 463 * and also hold the lock while remote shootdowns take place.
464 * This does not apply to the kernel pmap; all CPUs are notified about 464 * This does not apply to the kernel pmap; all CPUs are notified about
465 * invalidations for the kernel pmap, and the pmap lock is not held 465 * invalidations for the kernel pmap, and the pmap lock is not held
466 * in pmap_activate() for the kernel pmap. 466 * in pmap_activate() for the kernel pmap.
467 * 467 *
468 * ==> P->V operations (e.g. pmap_page_protect()) may require sending 468 * ==> P->V operations (e.g. pmap_page_protect()) may require sending
469 * invalidations for multiple address spaces. We only track one 469 * invalidations for multiple address spaces. We only track one
470 * address space at a time, and if we encounter more than one, then 470 * address space at a time, and if we encounter more than one, then
471 * the notification each CPU gets is to hit the entire TLB. Note 471 * the notification each CPU gets is to hit the entire TLB. Note
472 * also that we can't serialize with pmap_activate() in this case, 472 * also that we can't serialize with pmap_activate() in this case,
473 * so all CPUs will get the notification, and they check when 473 * so all CPUs will get the notification, and they check when
474 * processing the notification if the pmap is current on that CPU. 474 * processing the notification if the pmap is current on that CPU.
475 * 475 *
476 * Invalidation information is gathered into a pmap_tlb_context structure 476 * Invalidation information is gathered into a pmap_tlb_context structure
477 * that includes room for 8 VAs, the pmap the VAs belong to, a bitmap of 477 * that includes room for 8 VAs, the pmap the VAs belong to, a bitmap of
478 * CPUs to be notified, and a list for PT pages that are freed during 478 * CPUs to be notified, and a list for PT pages that are freed during
479 * removal off mappings. The number of valid addresses in the list as 479 * removal off mappings. The number of valid addresses in the list as
480 * well as flags are sqeezed into the lower bits of the first two VAs. 480 * well as flags are sqeezed into the lower bits of the first two VAs.
481 * Storage for this structure is allocated on the stack. We need to be 481 * Storage for this structure is allocated on the stack. We need to be
482 * careful to keep the size of this struture under control. 482 * careful to keep the size of this struture under control.
483 * 483 *
484 * When notifying remote CPUs, we acquire the tlb_lock (which also 484 * When notifying remote CPUs, we acquire the tlb_lock (which also
485 * blocks IPIs), record the pointer to our context structure, set a 485 * blocks IPIs), record the pointer to our context structure, set a
486 * global bitmap off CPUs to be notified, and then send the IPIs to 486 * global bitmap off CPUs to be notified, and then send the IPIs to
487 * each victim. While the other CPUs are in-flight, we then perform 487 * each victim. While the other CPUs are in-flight, we then perform
488 * any invalidations necessary on the local CPU. Once that is done, 488 * any invalidations necessary on the local CPU. Once that is done,
489 * we then wait the the global context pointer to be cleared, which 489 * we then wait the the global context pointer to be cleared, which
490 * will be done by the final remote CPU to complete their work. This 490 * will be done by the final remote CPU to complete their work. This
491 * method reduces cache line contention during pocessing. 491 * method reduces cache line contention during pocessing.
492 * 492 *
493 * When removing mappings in user pmaps, this implemention frees page 493 * When removing mappings in user pmaps, this implemention frees page
494 * table pages back to the VM system once they contain no valid mappings. 494 * table pages back to the VM system once they contain no valid mappings.
495 * As we do this, we must ensure to invalidate TLB entries that the 495 * As we do this, we must ensure to invalidate TLB entries that the
496 * CPU might hold for the respective recursive VPT mappings. This must 496 * CPU might hold for the respective recursive VPT mappings. This must
497 * be done whenever an L1 or L2 PTE is invalidated. Until these VPT 497 * be done whenever an L1 or L2 PTE is invalidated. Until these VPT
498 * translations are invalidated, the PT pages must not be reused. For 498 * translations are invalidated, the PT pages must not be reused. For
499 * this reason, we keep a list of freed PT pages in the context stucture 499 * this reason, we keep a list of freed PT pages in the context stucture
500 * and drain them off once all invalidations are complete. 500 * and drain them off once all invalidations are complete.
501 * 501 *
502 * NOTE: The value of TLB_CTX_MAXVA is tuned to accommodate the UBC 502 * NOTE: The value of TLB_CTX_MAXVA is tuned to accommodate the UBC
503 * window size (defined as 64KB on alpha in <machine/vmparam.h>). 503 * window size (defined as 64KB on alpha in <machine/vmparam.h>).
504 */ 504 */
505 505
506#define TLB_CTX_MAXVA 8 506#define TLB_CTX_MAXVA 8
507#define TLB_CTX_ALLVA PAGE_MASK 507#define TLB_CTX_ALLVA PAGE_MASK
508 508
509#define TLB_CTX_F_ASM __BIT(0) 509#define TLB_CTX_F_ASM __BIT(0)
510#define TLB_CTX_F_IMB __BIT(1) 510#define TLB_CTX_F_IMB __BIT(1)
511#define TLB_CTX_F_KIMB __BIT(2) 511#define TLB_CTX_F_KIMB __BIT(2)
512#define TLB_CTX_F_PV __BIT(3) 512#define TLB_CTX_F_PV __BIT(3)
513#define TLB_CTX_F_MULTI __BIT(4) 513#define TLB_CTX_F_MULTI __BIT(4)
514 514
515#define TLB_CTX_COUNT(ctx) ((ctx)->t_addrdata[0] & PAGE_MASK) 515#define TLB_CTX_COUNT(ctx) ((ctx)->t_addrdata[0] & PAGE_MASK)
516#define TLB_CTX_INC_COUNT(ctx) (ctx)->t_addrdata[0]++ 516#define TLB_CTX_INC_COUNT(ctx) (ctx)->t_addrdata[0]++
517#define TLB_CTX_SET_ALLVA(ctx) (ctx)->t_addrdata[0] |= TLB_CTX_ALLVA 517#define TLB_CTX_SET_ALLVA(ctx) (ctx)->t_addrdata[0] |= TLB_CTX_ALLVA
518 518
519#define TLB_CTX_FLAGS(ctx) ((ctx)->t_addrdata[1] & PAGE_MASK) 519#define TLB_CTX_FLAGS(ctx) ((ctx)->t_addrdata[1] & PAGE_MASK)
520#define TLB_CTX_SET_FLAG(ctx, f) (ctx)->t_addrdata[1] |= (f) 520#define TLB_CTX_SET_FLAG(ctx, f) (ctx)->t_addrdata[1] |= (f)
521 521
522#define TLB_CTX_VA(ctx, i) ((ctx)->t_addrdata[(i)] & ~PAGE_MASK) 522#define TLB_CTX_VA(ctx, i) ((ctx)->t_addrdata[(i)] & ~PAGE_MASK)
523#define TLB_CTX_SETVA(ctx, i, va) \ 523#define TLB_CTX_SETVA(ctx, i, va) \
524 (ctx)->t_addrdata[(i)] = (va) | ((ctx)->t_addrdata[(i)] & PAGE_MASK) 524 (ctx)->t_addrdata[(i)] = (va) | ((ctx)->t_addrdata[(i)] & PAGE_MASK)
525 525
526struct pmap_tlb_context { 526struct pmap_tlb_context {
527 uintptr_t t_addrdata[TLB_CTX_MAXVA]; 527 uintptr_t t_addrdata[TLB_CTX_MAXVA];
528 pmap_t t_pmap; 528 pmap_t t_pmap;
529 LIST_HEAD(, vm_page) t_freeptq; 529 LIST_HEAD(, vm_page) t_freeptq;
530}; 530};
531 531
532static struct { 532static struct {
533 kmutex_t lock; 533 kmutex_t lock;
534 struct evcnt events; 534 struct evcnt events;
535} tlb_shootdown __cacheline_aligned; 535} tlb_shootdown __cacheline_aligned;
536#define tlb_lock tlb_shootdown.lock 536#define tlb_lock tlb_shootdown.lock
537#define tlb_evcnt tlb_shootdown.events 537#define tlb_evcnt tlb_shootdown.events
538#if defined(MULTIPROCESSOR) 538#if defined(MULTIPROCESSOR)
539static const struct pmap_tlb_context *tlb_context __cacheline_aligned; 539static const struct pmap_tlb_context *tlb_context __cacheline_aligned;
540static unsigned long tlb_pending __cacheline_aligned; 540static unsigned long tlb_pending __cacheline_aligned;
541#endif /* MULTIPROCESSOR */ 541#endif /* MULTIPROCESSOR */
542 542
543#if defined(TLB_STATS) 543#if defined(TLB_STATS)
544#define TLB_COUNT_DECL(cnt) static struct evcnt tlb_stat_##cnt 544#define TLB_COUNT_DECL(cnt) static struct evcnt tlb_stat_##cnt
545#define TLB_COUNT(cnt) atomic_inc_64(&tlb_stat_##cnt .ev_count) 545#define TLB_COUNT(cnt) atomic_inc_64(&tlb_stat_##cnt .ev_count)
546#define TLB_COUNT_ATTACH(cnt) \ 546#define TLB_COUNT_ATTACH(cnt) \
547 evcnt_attach_dynamic_nozero(&tlb_stat_##cnt, EVCNT_TYPE_MISC, \ 547 evcnt_attach_dynamic_nozero(&tlb_stat_##cnt, EVCNT_TYPE_MISC, \
548 NULL, "TLB", #cnt) 548 NULL, "TLB", #cnt)
549 549
550TLB_COUNT_DECL(invalidate_multi_tbia); 550TLB_COUNT_DECL(invalidate_multi_tbia);
551TLB_COUNT_DECL(invalidate_multi_tbiap); 551TLB_COUNT_DECL(invalidate_multi_tbiap);
552TLB_COUNT_DECL(invalidate_multi_imb); 552TLB_COUNT_DECL(invalidate_multi_imb);
553 553
554TLB_COUNT_DECL(invalidate_kern_tbia); 554TLB_COUNT_DECL(invalidate_kern_tbia);
555TLB_COUNT_DECL(invalidate_kern_tbis); 555TLB_COUNT_DECL(invalidate_kern_tbis);
556TLB_COUNT_DECL(invalidate_kern_imb); 556TLB_COUNT_DECL(invalidate_kern_imb);
557 557
558TLB_COUNT_DECL(invalidate_user_not_current); 558TLB_COUNT_DECL(invalidate_user_not_current);
559TLB_COUNT_DECL(invalidate_user_lazy_imb); 559TLB_COUNT_DECL(invalidate_user_lazy_imb);
560TLB_COUNT_DECL(invalidate_user_tbiap); 560TLB_COUNT_DECL(invalidate_user_tbiap);
561TLB_COUNT_DECL(invalidate_user_tbis); 561TLB_COUNT_DECL(invalidate_user_tbis);
562 562
563TLB_COUNT_DECL(shootdown_kernel); 563TLB_COUNT_DECL(shootdown_kernel);
564TLB_COUNT_DECL(shootdown_user); 564TLB_COUNT_DECL(shootdown_user);
565TLB_COUNT_DECL(shootdown_imb); 565TLB_COUNT_DECL(shootdown_imb);
566TLB_COUNT_DECL(shootdown_kimb); 566TLB_COUNT_DECL(shootdown_kimb);
567TLB_COUNT_DECL(shootdown_overflow); 567TLB_COUNT_DECL(shootdown_overflow);
568 568
569TLB_COUNT_DECL(shootdown_all_user); 569TLB_COUNT_DECL(shootdown_all_user);
570TLB_COUNT_DECL(shootdown_all_user_imb); 570TLB_COUNT_DECL(shootdown_all_user_imb);
571 571
572TLB_COUNT_DECL(shootdown_pv); 572TLB_COUNT_DECL(shootdown_pv);
573TLB_COUNT_DECL(shootdown_pv_multi); 573TLB_COUNT_DECL(shootdown_pv_multi);
574 574
575TLB_COUNT_DECL(shootnow_over_notify); 575TLB_COUNT_DECL(shootnow_over_notify);
576TLB_COUNT_DECL(shootnow_remote); 576TLB_COUNT_DECL(shootnow_remote);
577 577
578TLB_COUNT_DECL(reason_remove_kernel); 578TLB_COUNT_DECL(reason_remove_kernel);
579TLB_COUNT_DECL(reason_remove_user); 579TLB_COUNT_DECL(reason_remove_user);
580TLB_COUNT_DECL(reason_page_protect_read); 580TLB_COUNT_DECL(reason_page_protect_read);
581TLB_COUNT_DECL(reason_page_protect_none); 581TLB_COUNT_DECL(reason_page_protect_none);
582TLB_COUNT_DECL(reason_protect); 582TLB_COUNT_DECL(reason_protect);
583TLB_COUNT_DECL(reason_enter_kernel); 583TLB_COUNT_DECL(reason_enter_kernel);
584TLB_COUNT_DECL(reason_enter_user); 584TLB_COUNT_DECL(reason_enter_user);
585TLB_COUNT_DECL(reason_kenter); 585TLB_COUNT_DECL(reason_kenter);
586TLB_COUNT_DECL(reason_enter_l2pt_delref); 586TLB_COUNT_DECL(reason_enter_l2pt_delref);
587TLB_COUNT_DECL(reason_enter_l3pt_delref); 587TLB_COUNT_DECL(reason_enter_l3pt_delref);
588TLB_COUNT_DECL(reason_kremove); 588TLB_COUNT_DECL(reason_kremove);
589TLB_COUNT_DECL(reason_clear_modify); 589TLB_COUNT_DECL(reason_clear_modify);
590TLB_COUNT_DECL(reason_clear_reference); 590TLB_COUNT_DECL(reason_clear_reference);
591TLB_COUNT_DECL(reason_emulate_reference); 591TLB_COUNT_DECL(reason_emulate_reference);
592 592
593TLB_COUNT_DECL(asn_reuse); 593TLB_COUNT_DECL(asn_reuse);
594TLB_COUNT_DECL(asn_newgen); 594TLB_COUNT_DECL(asn_newgen);
595TLB_COUNT_DECL(asn_assign); 595TLB_COUNT_DECL(asn_assign);
596 596
597TLB_COUNT_DECL(activate_both_change); 597TLB_COUNT_DECL(activate_both_change);
598TLB_COUNT_DECL(activate_asn_change); 598TLB_COUNT_DECL(activate_asn_change);
599TLB_COUNT_DECL(activate_ptbr_change); 599TLB_COUNT_DECL(activate_ptbr_change);
600TLB_COUNT_DECL(activate_swpctx); 600TLB_COUNT_DECL(activate_swpctx);
601TLB_COUNT_DECL(activate_skip_swpctx); 601TLB_COUNT_DECL(activate_skip_swpctx);
602 602
603#else /* ! TLB_STATS */ 603#else /* ! TLB_STATS */
604#define TLB_COUNT(cnt) __nothing 604#define TLB_COUNT(cnt) __nothing
605#define TLB_COUNT_ATTACH(cnt) __nothing 605#define TLB_COUNT_ATTACH(cnt) __nothing
606#endif /* TLB_STATS */ 606#endif /* TLB_STATS */
607 607
608static void 608static void
609pmap_tlb_init(void) 609pmap_tlb_init(void)
610{ 610{
611 /* mutex is initialized in pmap_bootstrap(). */ 611 /* mutex is initialized in pmap_bootstrap(). */
612 612
613 evcnt_attach_dynamic_nozero(&tlb_evcnt, EVCNT_TYPE_MISC, 613 evcnt_attach_dynamic_nozero(&tlb_evcnt, EVCNT_TYPE_MISC,
614 NULL, "TLB", "shootdown"); 614 NULL, "TLB", "shootdown");
615 615
616 TLB_COUNT_ATTACH(invalidate_multi_tbia); 616 TLB_COUNT_ATTACH(invalidate_multi_tbia);
617 TLB_COUNT_ATTACH(invalidate_multi_tbiap); 617 TLB_COUNT_ATTACH(invalidate_multi_tbiap);
618 TLB_COUNT_ATTACH(invalidate_multi_imb); 618 TLB_COUNT_ATTACH(invalidate_multi_imb);
619 619
620 TLB_COUNT_ATTACH(invalidate_kern_tbia); 620 TLB_COUNT_ATTACH(invalidate_kern_tbia);
621 TLB_COUNT_ATTACH(invalidate_kern_tbis); 621 TLB_COUNT_ATTACH(invalidate_kern_tbis);
622 TLB_COUNT_ATTACH(invalidate_kern_imb); 622 TLB_COUNT_ATTACH(invalidate_kern_imb);
623 623
624 TLB_COUNT_ATTACH(invalidate_user_not_current); 624 TLB_COUNT_ATTACH(invalidate_user_not_current);
625 TLB_COUNT_ATTACH(invalidate_user_lazy_imb); 625 TLB_COUNT_ATTACH(invalidate_user_lazy_imb);
626 TLB_COUNT_ATTACH(invalidate_user_tbiap); 626 TLB_COUNT_ATTACH(invalidate_user_tbiap);
627 TLB_COUNT_ATTACH(invalidate_user_tbis); 627 TLB_COUNT_ATTACH(invalidate_user_tbis);
628 628
629 TLB_COUNT_ATTACH(shootdown_kernel); 629 TLB_COUNT_ATTACH(shootdown_kernel);
630 TLB_COUNT_ATTACH(shootdown_user); 630 TLB_COUNT_ATTACH(shootdown_user);
631 TLB_COUNT_ATTACH(shootdown_imb); 631 TLB_COUNT_ATTACH(shootdown_imb);
632 TLB_COUNT_ATTACH(shootdown_kimb); 632 TLB_COUNT_ATTACH(shootdown_kimb);
633 TLB_COUNT_ATTACH(shootdown_overflow); 633 TLB_COUNT_ATTACH(shootdown_overflow);
634 634
635 TLB_COUNT_ATTACH(shootdown_all_user); 635 TLB_COUNT_ATTACH(shootdown_all_user);
636 TLB_COUNT_ATTACH(shootdown_all_user_imb); 636 TLB_COUNT_ATTACH(shootdown_all_user_imb);
637 637
638 TLB_COUNT_ATTACH(shootdown_pv); 638 TLB_COUNT_ATTACH(shootdown_pv);
639 TLB_COUNT_ATTACH(shootdown_pv_multi); 639 TLB_COUNT_ATTACH(shootdown_pv_multi);
640 640
641 TLB_COUNT_ATTACH(shootnow_over_notify); 641 TLB_COUNT_ATTACH(shootnow_over_notify);
642 TLB_COUNT_ATTACH(shootnow_remote); 642 TLB_COUNT_ATTACH(shootnow_remote);
643 643
644 TLB_COUNT_ATTACH(reason_remove_kernel); 644 TLB_COUNT_ATTACH(reason_remove_kernel);
645 TLB_COUNT_ATTACH(reason_remove_user); 645 TLB_COUNT_ATTACH(reason_remove_user);
646 TLB_COUNT_ATTACH(reason_page_protect_read); 646 TLB_COUNT_ATTACH(reason_page_protect_read);
647 TLB_COUNT_ATTACH(reason_page_protect_none); 647 TLB_COUNT_ATTACH(reason_page_protect_none);
648 TLB_COUNT_ATTACH(reason_protect); 648 TLB_COUNT_ATTACH(reason_protect);
649 TLB_COUNT_ATTACH(reason_enter_kernel); 649 TLB_COUNT_ATTACH(reason_enter_kernel);
650 TLB_COUNT_ATTACH(reason_enter_user); 650 TLB_COUNT_ATTACH(reason_enter_user);
651 TLB_COUNT_ATTACH(reason_kenter); 651 TLB_COUNT_ATTACH(reason_kenter);
652 TLB_COUNT_ATTACH(reason_enter_l2pt_delref); 652 TLB_COUNT_ATTACH(reason_enter_l2pt_delref);
653 TLB_COUNT_ATTACH(reason_enter_l3pt_delref); 653 TLB_COUNT_ATTACH(reason_enter_l3pt_delref);
654 TLB_COUNT_ATTACH(reason_kremove); 654 TLB_COUNT_ATTACH(reason_kremove);
655 TLB_COUNT_ATTACH(reason_clear_modify); 655 TLB_COUNT_ATTACH(reason_clear_modify);
656 TLB_COUNT_ATTACH(reason_clear_reference); 656 TLB_COUNT_ATTACH(reason_clear_reference);
657 657
658 TLB_COUNT_ATTACH(asn_reuse); 658 TLB_COUNT_ATTACH(asn_reuse);
659 TLB_COUNT_ATTACH(asn_newgen); 659 TLB_COUNT_ATTACH(asn_newgen);
660 TLB_COUNT_ATTACH(asn_assign); 660 TLB_COUNT_ATTACH(asn_assign);
661 661
662 TLB_COUNT_ATTACH(activate_both_change); 662 TLB_COUNT_ATTACH(activate_both_change);
663 TLB_COUNT_ATTACH(activate_asn_change); 663 TLB_COUNT_ATTACH(activate_asn_change);
664 TLB_COUNT_ATTACH(activate_ptbr_change); 664 TLB_COUNT_ATTACH(activate_ptbr_change);
665 TLB_COUNT_ATTACH(activate_swpctx); 665 TLB_COUNT_ATTACH(activate_swpctx);
666 TLB_COUNT_ATTACH(activate_skip_swpctx); 666 TLB_COUNT_ATTACH(activate_skip_swpctx);
667} 667}
668 668
669static inline void 669static inline void
670pmap_tlb_context_init(struct pmap_tlb_context * const tlbctx, uintptr_t flags) 670pmap_tlb_context_init(struct pmap_tlb_context * const tlbctx, uintptr_t flags)
671{ 671{
672 /* Initialize the minimum number of fields. */ 672 /* Initialize the minimum number of fields. */
673 tlbctx->t_addrdata[0] = 0; 673 tlbctx->t_addrdata[0] = 0;
674 tlbctx->t_addrdata[1] = flags; 674 tlbctx->t_addrdata[1] = flags;
675 tlbctx->t_pmap = NULL; 675 tlbctx->t_pmap = NULL;
676 LIST_INIT(&tlbctx->t_freeptq); 676 LIST_INIT(&tlbctx->t_freeptq);
677} 677}
678 678
679static void 679static void
680pmap_tlb_shootdown_internal(pmap_t const pmap, vaddr_t const va, 680pmap_tlb_shootdown_internal(pmap_t const pmap, vaddr_t const va,
681 pt_entry_t const pte_bits, struct pmap_tlb_context * const tlbctx) 681 pt_entry_t const pte_bits, struct pmap_tlb_context * const tlbctx)
682{ 682{
683 KASSERT(pmap != NULL); 683 KASSERT(pmap != NULL);
684 KASSERT((va & PAGE_MASK) == 0); 684 KASSERT((va & PAGE_MASK) == 0);
685 685
686 /* 686 /*
687 * Figure out who needs to hear about this, and the scope 687 * Figure out who needs to hear about this, and the scope
688 * of an all-entries invalidate. 688 * of an all-entries invalidate.
689 */ 689 */
690 if (pmap == pmap_kernel()) { 690 if (pmap == pmap_kernel()) {
691 TLB_COUNT(shootdown_kernel); 691 TLB_COUNT(shootdown_kernel);
692 KASSERT(pte_bits & PG_ASM); 692 KASSERT(pte_bits & PG_ASM);
693 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_ASM); 693 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_ASM);
694 694
695 /* Note if an I-stream sync is also needed. */ 695 /* Note if an I-stream sync is also needed. */
696 if (pte_bits & PG_EXEC) { 696 if (pte_bits & PG_EXEC) {
697 TLB_COUNT(shootdown_kimb); 697 TLB_COUNT(shootdown_kimb);
698 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_KIMB); 698 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_KIMB);
699 } 699 }
700 } else { 700 } else {
701 TLB_COUNT(shootdown_user); 701 TLB_COUNT(shootdown_user);
702 KASSERT((pte_bits & PG_ASM) == 0); 702 KASSERT((pte_bits & PG_ASM) == 0);
703 703
704 /* Note if an I-stream sync is also needed. */ 704 /* Note if an I-stream sync is also needed. */
705 if (pte_bits & PG_EXEC) { 705 if (pte_bits & PG_EXEC) {
706 TLB_COUNT(shootdown_imb); 706 TLB_COUNT(shootdown_imb);
707 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_IMB); 707 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_IMB);
708 } 708 }
709 } 709 }
710 710
711 KASSERT(tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap); 711 KASSERT(tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap);
712 tlbctx->t_pmap = pmap; 712 tlbctx->t_pmap = pmap;
713 713
714 /* 714 /*
715 * If we're already at the max, just tell each active CPU 715 * If we're already at the max, just tell each active CPU
716 * to nail everything. 716 * to nail everything.
717 */ 717 */
718 const uintptr_t count = TLB_CTX_COUNT(tlbctx); 718 const uintptr_t count = TLB_CTX_COUNT(tlbctx);
719 if (count > TLB_CTX_MAXVA) { 719 if (count > TLB_CTX_MAXVA) {
720 return; 720 return;
721 } 721 }
722 if (count == TLB_CTX_MAXVA) { 722 if (count == TLB_CTX_MAXVA) {
723 TLB_COUNT(shootdown_overflow); 723 TLB_COUNT(shootdown_overflow);
724 TLB_CTX_SET_ALLVA(tlbctx); 724 TLB_CTX_SET_ALLVA(tlbctx);
725 return; 725 return;
726 } 726 }
727 727
728 TLB_CTX_SETVA(tlbctx, count, va); 728 TLB_CTX_SETVA(tlbctx, count, va);
729 TLB_CTX_INC_COUNT(tlbctx); 729 TLB_CTX_INC_COUNT(tlbctx);
730} 730}
731 731
732static void 732static void
733pmap_tlb_shootdown(pmap_t const pmap, vaddr_t const va, 733pmap_tlb_shootdown(pmap_t const pmap, vaddr_t const va,
734 pt_entry_t const pte_bits, struct pmap_tlb_context * const tlbctx) 734 pt_entry_t const pte_bits, struct pmap_tlb_context * const tlbctx)
735{ 735{
736 KASSERT((TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV) == 0); 736 KASSERT((TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV) == 0);
737 pmap_tlb_shootdown_internal(pmap, va, pte_bits, tlbctx); 737 pmap_tlb_shootdown_internal(pmap, va, pte_bits, tlbctx);
738} 738}
739 739
740static void 740static void
741pmap_tlb_shootdown_all_user(pmap_t const pmap, pt_entry_t const pte_bits, 741pmap_tlb_shootdown_all_user(pmap_t const pmap, pt_entry_t const pte_bits,
742 struct pmap_tlb_context * const tlbctx) 742 struct pmap_tlb_context * const tlbctx)
743{ 743{
744 KASSERT(pmap != pmap_kernel()); 744 KASSERT(pmap != pmap_kernel());
745 745
746 TLB_COUNT(shootdown_all_user); 746 TLB_COUNT(shootdown_all_user);
747 747
748 /* Note if an I-stream sync is also needed. */ 748 /* Note if an I-stream sync is also needed. */
749 if (pte_bits & PG_EXEC) { 749 if (pte_bits & PG_EXEC) {
750 TLB_COUNT(shootdown_all_user_imb); 750 TLB_COUNT(shootdown_all_user_imb);
751 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_IMB); 751 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_IMB);
752 } 752 }
753 753
754 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV) { 754 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV) {
755 if (tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap) { 755 if (tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap) {
756 if (tlbctx->t_pmap == NULL) { 756 if (tlbctx->t_pmap == NULL) {
757 pmap_reference(pmap); 757 pmap_reference(pmap);
758 tlbctx->t_pmap = pmap; 758 tlbctx->t_pmap = pmap;
759 } 759 }
760 } else { 760 } else {
761 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_MULTI); 761 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_MULTI);
762 } 762 }
763 } else { 763 } else {
764 KASSERT(tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap); 764 KASSERT(tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap);
765 tlbctx->t_pmap = pmap; 765 tlbctx->t_pmap = pmap;
766 } 766 }
767 767
768 TLB_CTX_SET_ALLVA(tlbctx); 768 TLB_CTX_SET_ALLVA(tlbctx);
769} 769}
770 770
771static void 771static void
772pmap_tlb_shootdown_pv(pmap_t const pmap, vaddr_t const va, 772pmap_tlb_shootdown_pv(pmap_t const pmap, vaddr_t const va,
773 pt_entry_t const pte_bits, struct pmap_tlb_context * const tlbctx) 773 pt_entry_t const pte_bits, struct pmap_tlb_context * const tlbctx)
774{ 774{
775 775
776 KASSERT(TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV); 776 KASSERT(TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV);
777 777
778 TLB_COUNT(shootdown_pv); 778 TLB_COUNT(shootdown_pv);
779 779
780 if (tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap) { 780 if (tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap) {
781 if (tlbctx->t_pmap == NULL) { 781 if (tlbctx->t_pmap == NULL) {
782 pmap_reference(pmap); 782 pmap_reference(pmap);
783 tlbctx->t_pmap = pmap; 783 tlbctx->t_pmap = pmap;
784 } 784 }
785 pmap_tlb_shootdown_internal(pmap, va, pte_bits, tlbctx); 785 pmap_tlb_shootdown_internal(pmap, va, pte_bits, tlbctx);
786 } else { 786 } else {
787 TLB_COUNT(shootdown_pv_multi); 787 TLB_COUNT(shootdown_pv_multi);
788 uintptr_t flags = TLB_CTX_F_MULTI; 788 uintptr_t flags = TLB_CTX_F_MULTI;
789 if (pmap == pmap_kernel()) { 789 if (pmap == pmap_kernel()) {
790 KASSERT(pte_bits & PG_ASM); 790 KASSERT(pte_bits & PG_ASM);
791 flags |= TLB_CTX_F_ASM; 791 flags |= TLB_CTX_F_ASM;
792 } else { 792 } else {
793 KASSERT((pte_bits & PG_ASM) == 0); 793 KASSERT((pte_bits & PG_ASM) == 0);
794 } 794 }
795 795
796 /* 796 /*
797 * No need to distinguish between kernel and user IMB 797 * No need to distinguish between kernel and user IMB
798 * here; see pmap_tlb_invalidate_multi(). 798 * here; see pmap_tlb_invalidate_multi().
799 */ 799 */
800 if (pte_bits & PG_EXEC) { 800 if (pte_bits & PG_EXEC) {
801 flags |= TLB_CTX_F_IMB; 801 flags |= TLB_CTX_F_IMB;
802 } 802 }
803 TLB_CTX_SET_ALLVA(tlbctx); 803 TLB_CTX_SET_ALLVA(tlbctx);
804 TLB_CTX_SET_FLAG(tlbctx, flags); 804 TLB_CTX_SET_FLAG(tlbctx, flags);
805 } 805 }
806} 806}
807 807
808static void 808static void
809pmap_tlb_invalidate_multi(const struct pmap_tlb_context * const tlbctx) 809pmap_tlb_invalidate_multi(const struct pmap_tlb_context * const tlbctx)
810{ 810{
811 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_ASM) { 811 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_ASM) {
812 TLB_COUNT(invalidate_multi_tbia); 812 TLB_COUNT(invalidate_multi_tbia);
813 ALPHA_TBIA(); 813 ALPHA_TBIA();
814 } else { 814 } else {
815 TLB_COUNT(invalidate_multi_tbiap); 815 TLB_COUNT(invalidate_multi_tbiap);
816 ALPHA_TBIAP(); 816 ALPHA_TBIAP();
817 } 817 }
818 if (TLB_CTX_FLAGS(tlbctx) & (TLB_CTX_F_IMB | TLB_CTX_F_KIMB)) { 818 if (TLB_CTX_FLAGS(tlbctx) & (TLB_CTX_F_IMB | TLB_CTX_F_KIMB)) {
819 TLB_COUNT(invalidate_multi_imb); 819 TLB_COUNT(invalidate_multi_imb);
820 alpha_pal_imb(); 820 alpha_pal_imb();
821 } 821 }
822} 822}
823 823
824static void 824static void
825pmap_tlb_invalidate_kernel(const struct pmap_tlb_context * const tlbctx) 825pmap_tlb_invalidate_kernel(const struct pmap_tlb_context * const tlbctx)
826{ 826{
827 const uintptr_t count = TLB_CTX_COUNT(tlbctx); 827 const uintptr_t count = TLB_CTX_COUNT(tlbctx);
828 828
829 if (count == TLB_CTX_ALLVA) { 829 if (count == TLB_CTX_ALLVA) {
830 TLB_COUNT(invalidate_kern_tbia); 830 TLB_COUNT(invalidate_kern_tbia);
831 ALPHA_TBIA(); 831 ALPHA_TBIA();
832 } else { 832 } else {
833 TLB_COUNT(invalidate_kern_tbis); 833 TLB_COUNT(invalidate_kern_tbis);
834 for (uintptr_t i = 0; i < count; i++) { 834 for (uintptr_t i = 0; i < count; i++) {
835 ALPHA_TBIS(TLB_CTX_VA(tlbctx, i)); 835 ALPHA_TBIS(TLB_CTX_VA(tlbctx, i));
836 } 836 }
837 } 837 }
838 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_KIMB) { 838 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_KIMB) {
839 TLB_COUNT(invalidate_kern_imb); 839 TLB_COUNT(invalidate_kern_imb);
840 alpha_pal_imb(); 840 alpha_pal_imb();
841 } 841 }
842} 842}
843 843
844static void 844static void
845pmap_tlb_invalidate(const struct pmap_tlb_context * const tlbctx, 845pmap_tlb_invalidate(const struct pmap_tlb_context * const tlbctx,
846 const struct cpu_info * const ci) 846 const struct cpu_info * const ci)
847{ 847{
848 const uintptr_t count = TLB_CTX_COUNT(tlbctx); 848 const uintptr_t count = TLB_CTX_COUNT(tlbctx);
849 849
850 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_MULTI) { 850 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_MULTI) {
851 pmap_tlb_invalidate_multi(tlbctx); 851 pmap_tlb_invalidate_multi(tlbctx);
852 return; 852 return;
853 } 853 }
854 854
855 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_ASM) { 855 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_ASM) {
856 pmap_tlb_invalidate_kernel(tlbctx); 856 pmap_tlb_invalidate_kernel(tlbctx);
857 return; 857 return;
858 } 858 }
859 859
860 KASSERT(kpreempt_disabled()); 860 KASSERT(kpreempt_disabled());
861 861
862 pmap_t const pmap = tlbctx->t_pmap; 862 pmap_t const pmap = tlbctx->t_pmap;
863 KASSERT(pmap != NULL); 863 KASSERT(pmap != NULL);
864 864
865 const u_long cpu_mask = 1UL << ci->ci_cpuid; 865 const u_long cpu_mask = 1UL << ci->ci_cpuid;
866 866
867 if (__predict_false(pmap != ci->ci_pmap)) { 867 if (__predict_false(pmap != ci->ci_pmap)) {
868 TLB_COUNT(invalidate_user_not_current); 868 TLB_COUNT(invalidate_user_not_current);
869 869
870 /* 870 /*
871 * For CPUs that don't implement ASNs, the SWPCTX call 871 * For CPUs that don't implement ASNs, the SWPCTX call
872 * does all of the TLB invalidation work for us. 872 * does all of the TLB invalidation work for us.
873 */ 873 */
874 if (__predict_false(pmap_max_asn == 0)) { 874 if (__predict_false(pmap_max_asn == 0)) {
875 return; 875 return;
876 } 876 }
877 877
878 /* 878 /*
879 * We cannot directly invalidate the TLB in this case, 879 * We cannot directly invalidate the TLB in this case,
880 * so force allocation of a new ASN when the pmap becomes 880 * so force allocation of a new ASN when the pmap becomes
881 * active again. 881 * active again.
882 */ 882 */
883 pmap->pm_asni[ci->ci_cpuid].pma_asngen = PMAP_ASNGEN_INVALID; 883 pmap->pm_percpu[ci->ci_cpuid].pmc_asngen = PMAP_ASNGEN_INVALID;
884 atomic_and_ulong(&pmap->pm_cpus, ~cpu_mask); 884 atomic_and_ulong(&pmap->pm_cpus, ~cpu_mask);
885 885
886 /* 886 /*
887 * This isn't strictly necessary; when we allocate a 887 * This isn't strictly necessary; when we allocate a
888 * new ASN, we're going to clear this bit and skip 888 * new ASN, we're going to clear this bit and skip
889 * syncing the I-stream. But we will keep this bit 889 * syncing the I-stream. But we will keep this bit
890 * of accounting for internal consistency. 890 * of accounting for internal consistency.
891 */ 891 */
892 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_IMB) { 892 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_IMB) {
893 atomic_or_ulong(&pmap->pm_needisync, cpu_mask); 893 atomic_or_ulong(&pmap->pm_needisync, cpu_mask);
894 } 894 }
895 return; 895 return;
896 } 896 }
897 897
898 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_IMB) { 898 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_IMB) {
899 TLB_COUNT(invalidate_user_lazy_imb); 899 TLB_COUNT(invalidate_user_lazy_imb);
900 atomic_or_ulong(&pmap->pm_needisync, cpu_mask); 900 atomic_or_ulong(&pmap->pm_needisync, cpu_mask);
901 } 901 }
902 902
903 if (count == TLB_CTX_ALLVA) { 903 if (count == TLB_CTX_ALLVA) {
904 /* 904 /*
905 * Another option here for CPUs that implement ASNs is 905 * Another option here for CPUs that implement ASNs is
906 * to allocate a new ASN and do a SWPCTX. That's almost 906 * to allocate a new ASN and do a SWPCTX. That's almost
907 * certainly faster than a TBIAP, but would require us 907 * certainly faster than a TBIAP, but would require us
908 * to synchronize against IPIs in pmap_activate(). 908 * to synchronize against IPIs in pmap_activate().
909 */ 909 */
910 TLB_COUNT(invalidate_user_tbiap); 910 TLB_COUNT(invalidate_user_tbiap);
911 KASSERT((TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_ASM) == 0); 911 KASSERT((TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_ASM) == 0);
912 ALPHA_TBIAP(); 912 ALPHA_TBIAP();
913 } else { 913 } else {
914 TLB_COUNT(invalidate_user_tbis); 914 TLB_COUNT(invalidate_user_tbis);
915 for (uintptr_t i = 0; i < count; i++) { 915 for (uintptr_t i = 0; i < count; i++) {
916 ALPHA_TBIS(TLB_CTX_VA(tlbctx, i)); 916 ALPHA_TBIS(TLB_CTX_VA(tlbctx, i));
917 } 917 }
918 } 918 }
919} 919}
920 920
921static void 921static void
922pmap_tlb_shootnow(const struct pmap_tlb_context * const tlbctx) 922pmap_tlb_shootnow(const struct pmap_tlb_context * const tlbctx)
923{ 923{
924 924
925 if (TLB_CTX_COUNT(tlbctx) == 0) { 925 if (TLB_CTX_COUNT(tlbctx) == 0) {
926 /* No work to do. */ 926 /* No work to do. */
927 return; 927 return;
928 } 928 }
929 929
930 /* 930 /*
931 * Acquire the shootdown mutex. This will also block IPL_VM 931 * Acquire the shootdown mutex. This will also block IPL_VM
932 * interrupts and disable preemption. It is critically important 932 * interrupts and disable preemption. It is critically important
933 * that IPIs not be blocked in this routine. 933 * that IPIs not be blocked in this routine.
934 */ 934 */
935 KASSERT((alpha_pal_rdps() & ALPHA_PSL_IPL_MASK) < ALPHA_PSL_IPL_CLOCK); 935 KASSERT((alpha_pal_rdps() & ALPHA_PSL_IPL_MASK) < ALPHA_PSL_IPL_CLOCK);
936 mutex_spin_enter(&tlb_lock); 936 mutex_spin_enter(&tlb_lock);
937 tlb_evcnt.ev_count++; 937 tlb_evcnt.ev_count++;
938 938
939 const struct cpu_info *ci = curcpu(); 939 const struct cpu_info *ci = curcpu();
940 const u_long this_cpu = 1UL << ci->ci_cpuid; 940 const u_long this_cpu = 1UL << ci->ci_cpuid;
941 u_long active_cpus; 941 u_long active_cpus;
942 bool activation_locked, activation_lock_tried; 942 bool activation_locked, activation_lock_tried;
943 943
944 /* 944 /*
945 * Figure out who to notify. If it's for the kernel or 945 * Figure out who to notify. If it's for the kernel or
946 * multiple aaddress spaces, we notify everybody. If 946 * multiple aaddress spaces, we notify everybody. If
947 * it's a single user pmap, then we try to acquire the 947 * it's a single user pmap, then we try to acquire the
948 * activation lock so we can get an accurate accounting 948 * activation lock so we can get an accurate accounting
949 * of who needs to be notified. If we can't acquire 949 * of who needs to be notified. If we can't acquire
950 * the activation lock, then just notify everyone and 950 * the activation lock, then just notify everyone and
951 * let them sort it out when they process the IPI. 951 * let them sort it out when they process the IPI.
952 */ 952 */
953 if (TLB_CTX_FLAGS(tlbctx) & (TLB_CTX_F_ASM | TLB_CTX_F_MULTI)) { 953 if (TLB_CTX_FLAGS(tlbctx) & (TLB_CTX_F_ASM | TLB_CTX_F_MULTI)) {
954 active_cpus = pmap_all_cpus(); 954 active_cpus = pmap_all_cpus();
955 activation_locked = false; 955 activation_locked = false;
956 activation_lock_tried = false; 956 activation_lock_tried = false;
957 } else { 957 } else {
958 KASSERT(tlbctx->t_pmap != NULL); 958 KASSERT(tlbctx->t_pmap != NULL);
959 activation_locked = PMAP_ACT_TRYLOCK(tlbctx->t_pmap); 959 activation_locked = PMAP_ACT_TRYLOCK(tlbctx->t_pmap);
960 if (__predict_true(activation_locked)) { 960 if (__predict_true(activation_locked)) {
961 active_cpus = tlbctx->t_pmap->pm_cpus; 961 active_cpus = tlbctx->t_pmap->pm_cpus;
962 } else { 962 } else {
963 TLB_COUNT(shootnow_over_notify); 963 TLB_COUNT(shootnow_over_notify);
964 active_cpus = pmap_all_cpus(); 964 active_cpus = pmap_all_cpus();
965 } 965 }
966 activation_lock_tried = true; 966 activation_lock_tried = true;
967 } 967 }
968 968
969#if defined(MULTIPROCESSOR) 969#if defined(MULTIPROCESSOR)
970 /* 970 /*
971 * If there are remote CPUs that need to do work, get them 971 * If there are remote CPUs that need to do work, get them
972 * started now. 972 * started now.
973 */ 973 */
974 const u_long remote_cpus = active_cpus & ~this_cpu; 974 const u_long remote_cpus = active_cpus & ~this_cpu;
975 KASSERT(tlb_context == NULL); 975 KASSERT(tlb_context == NULL);
976 if (remote_cpus) { 976 if (remote_cpus) {
977 TLB_COUNT(shootnow_remote); 977 TLB_COUNT(shootnow_remote);
978 tlb_context = tlbctx; 978 tlb_context = tlbctx;
979 tlb_pending = remote_cpus; 979 tlb_pending = remote_cpus;
980 alpha_multicast_ipi(remote_cpus, ALPHA_IPI_SHOOTDOWN); 980 alpha_multicast_ipi(remote_cpus, ALPHA_IPI_SHOOTDOWN);
981 } 981 }
982#endif /* MULTIPROCESSOR */ 982#endif /* MULTIPROCESSOR */
983 983
984 /* 984 /*
985 * Now that the remotes have been notified, release the 985 * Now that the remotes have been notified, release the
986 * activation lock. 986 * activation lock.
987 */ 987 */
988 if (activation_lock_tried) { 988 if (activation_lock_tried) {
989 if (activation_locked) { 989 if (activation_locked) {
990 KASSERT(tlbctx->t_pmap != NULL); 990 KASSERT(tlbctx->t_pmap != NULL);
991 PMAP_ACT_UNLOCK(tlbctx->t_pmap); 991 PMAP_ACT_UNLOCK(tlbctx->t_pmap);
992 } 992 }
993 /* 993 /*
994 * When we tried to acquire the activation lock, we 994 * When we tried to acquire the activation lock, we
995 * raised IPL to IPL_SCHED (even if we ultimately 995 * raised IPL to IPL_SCHED (even if we ultimately
996 * failed to acquire the lock), which blocks out IPIs. 996 * failed to acquire the lock), which blocks out IPIs.
997 * Force our IPL back down to IPL_VM so that we can 997 * Force our IPL back down to IPL_VM so that we can
998 * receive IPIs. 998 * receive IPIs.
999 */ 999 */
1000 alpha_pal_swpipl(IPL_VM); 1000 alpha_pal_swpipl(IPL_VM);
1001 } 1001 }
1002 1002
1003 /* 1003 /*
1004 * Do any work that we might need to do. We don't need to 1004 * Do any work that we might need to do. We don't need to
1005 * synchronize with activation here because we know that 1005 * synchronize with activation here because we know that
1006 * for the current CPU, activation status will not change. 1006 * for the current CPU, activation status will not change.
1007 */ 1007 */
1008 if (active_cpus & this_cpu) { 1008 if (active_cpus & this_cpu) {
1009 pmap_tlb_invalidate(tlbctx, ci); 1009 pmap_tlb_invalidate(tlbctx, ci);
1010 } 1010 }
1011 1011
1012#if defined(MULTIPROCESSOR) 1012#if defined(MULTIPROCESSOR)
1013 /* Wait for remote CPUs to finish. */ 1013 /* Wait for remote CPUs to finish. */
1014 if (remote_cpus) { 1014 if (remote_cpus) {
1015 int backoff = SPINLOCK_BACKOFF_MIN; 1015 int backoff = SPINLOCK_BACKOFF_MIN;
1016 u_int spins = 0; 1016 u_int spins = 0;
1017 1017
1018 while (atomic_load_acquire(&tlb_context) != NULL) { 1018 while (atomic_load_acquire(&tlb_context) != NULL) {
1019 SPINLOCK_BACKOFF(backoff); 1019 SPINLOCK_BACKOFF(backoff);
1020 if (spins++ > 0x0fffffff) { 1020 if (spins++ > 0x0fffffff) {
1021 printf("TLB LOCAL MASK = 0x%016lx\n", 1021 printf("TLB LOCAL MASK = 0x%016lx\n",
1022 this_cpu); 1022 this_cpu);
1023 printf("TLB REMOTE MASK = 0x%016lx\n", 1023 printf("TLB REMOTE MASK = 0x%016lx\n",
1024 remote_cpus); 1024 remote_cpus);
1025 printf("TLB REMOTE PENDING = 0x%016lx\n", 1025 printf("TLB REMOTE PENDING = 0x%016lx\n",
1026 tlb_pending); 1026 tlb_pending);
1027 printf("TLB CONTEXT = %p\n", tlb_context); 1027 printf("TLB CONTEXT = %p\n", tlb_context);
1028 printf("TLB LOCAL IPL = %lu\n", 1028 printf("TLB LOCAL IPL = %lu\n",
1029 alpha_pal_rdps() & ALPHA_PSL_IPL_MASK); 1029 alpha_pal_rdps() & ALPHA_PSL_IPL_MASK);
1030 panic("pmap_tlb_shootnow"); 1030 panic("pmap_tlb_shootnow");
1031 } 1031 }
1032 } 1032 }
1033 } 1033 }
1034 KASSERT(tlb_context == NULL); 1034 KASSERT(tlb_context == NULL);
1035#endif /* MULTIPROCESSOR */ 1035#endif /* MULTIPROCESSOR */
1036 1036
1037 mutex_spin_exit(&tlb_lock); 1037 mutex_spin_exit(&tlb_lock);
1038 1038
1039 if (__predict_false(TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV)) { 1039 if (__predict_false(TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV)) {
1040 /* 1040 /*
1041 * P->V TLB operations may operate on multiple pmaps. 1041 * P->V TLB operations may operate on multiple pmaps.
1042 * The shootdown takes a reference on the first pmap it 1042 * The shootdown takes a reference on the first pmap it
1043 * encounters, in order to prevent it from disappearing, 1043 * encounters, in order to prevent it from disappearing,
1044 * in the hope that we end up with a single-pmap P->V 1044 * in the hope that we end up with a single-pmap P->V
1045 * operation (instrumentation shows this is not rare). 1045 * operation (instrumentation shows this is not rare).
1046 * 1046 *
1047 * Once this shootdown is finished globally, we need to 1047 * Once this shootdown is finished globally, we need to
1048 * release this extra reference. 1048 * release this extra reference.
1049 */ 1049 */
1050 KASSERT(tlbctx->t_pmap != NULL); 1050 KASSERT(tlbctx->t_pmap != NULL);
1051 pmap_destroy(tlbctx->t_pmap); 1051 pmap_destroy(tlbctx->t_pmap);
1052 } 1052 }
1053} 1053}
1054 1054
1055#if defined(MULTIPROCESSOR) 1055#if defined(MULTIPROCESSOR)
1056void 1056void
1057pmap_tlb_shootdown_ipi(struct cpu_info * const ci, 1057pmap_tlb_shootdown_ipi(struct cpu_info * const ci,
1058 1058
1059 struct trapframe * const tf __unused) 1059 struct trapframe * const tf __unused)
1060{ 1060{
1061 KASSERT(tlb_context != NULL); 1061 KASSERT(tlb_context != NULL);
1062 pmap_tlb_invalidate(tlb_context, ci); 1062 pmap_tlb_invalidate(tlb_context, ci);
1063 if (atomic_and_ulong_nv(&tlb_pending, ~(1UL << ci->ci_cpuid)) == 0) { 1063 if (atomic_and_ulong_nv(&tlb_pending, ~(1UL << ci->ci_cpuid)) == 0) {
1064 atomic_store_release(&tlb_context, NULL); 1064 atomic_store_release(&tlb_context, NULL);
1065 } 1065 }
1066} 1066}
1067#endif /* MULTIPROCESSOR */ 1067#endif /* MULTIPROCESSOR */
1068 1068
1069static void 1069static void
1070pmap_tlb_physpage_free(paddr_t const ptpa, 1070pmap_tlb_physpage_free(paddr_t const ptpa,
1071 struct pmap_tlb_context * const tlbctx) 1071 struct pmap_tlb_context * const tlbctx)
1072{ 1072{
1073 struct vm_page * const pg = PHYS_TO_VM_PAGE(ptpa); 1073 struct vm_page * const pg = PHYS_TO_VM_PAGE(ptpa);
1074 1074
1075 KASSERT(pg != NULL); 1075 KASSERT(pg != NULL);
1076 1076
1077#ifdef DEBUG 1077#ifdef DEBUG
1078 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 1078 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
1079 KDASSERT(md->pvh_refcnt == 0); 1079 KDASSERT(md->pvh_refcnt == 0);
1080#endif 1080#endif
1081 1081
1082 LIST_INSERT_HEAD(&tlbctx->t_freeptq, pg, pageq.list); 1082 LIST_INSERT_HEAD(&tlbctx->t_freeptq, pg, pageq.list);
1083} 1083}
1084 1084
1085static void 1085static void
1086pmap_tlb_ptpage_drain(struct pmap_tlb_context * const tlbctx) 1086pmap_tlb_ptpage_drain(struct pmap_tlb_context * const tlbctx)
1087{ 1087{
1088 struct vm_page *pg; 1088 struct vm_page *pg;
1089 1089
1090 while ((pg = LIST_FIRST(&tlbctx->t_freeptq)) != NULL) { 1090 while ((pg = LIST_FIRST(&tlbctx->t_freeptq)) != NULL) {
1091 LIST_REMOVE(pg, pageq.list); 1091 LIST_REMOVE(pg, pageq.list);
1092 uvm_pagefree(pg); 1092 uvm_pagefree(pg);
1093 } 1093 }
1094} 1094}
1095 1095
1096/* 1096/*
1097 * Internal routines 1097 * Internal routines
1098 */ 1098 */
1099static void alpha_protection_init(void); 1099static void alpha_protection_init(void);
1100static pt_entry_t pmap_remove_mapping(pmap_t, vaddr_t, pt_entry_t *, bool, 1100static pt_entry_t pmap_remove_mapping(pmap_t, vaddr_t, pt_entry_t *, bool,
1101 pv_entry_t *, 1101 pv_entry_t *,
1102 struct pmap_tlb_context *); 1102 struct pmap_tlb_context *);
1103static void pmap_changebit(struct vm_page *, pt_entry_t, pt_entry_t, 1103static void pmap_changebit(struct vm_page *, pt_entry_t, pt_entry_t,
1104 struct pmap_tlb_context *); 1104 struct pmap_tlb_context *);
1105 1105
1106/* 1106/*
1107 * PT page management functions. 1107 * PT page management functions.
1108 */ 1108 */
1109static int pmap_ptpage_alloc(pt_entry_t *, int); 1109static int pmap_ptpage_alloc(pt_entry_t *, int);
1110static void pmap_ptpage_free(pt_entry_t *, struct pmap_tlb_context *); 1110static void pmap_ptpage_free(pt_entry_t *, struct pmap_tlb_context *);
1111static void pmap_l3pt_delref(pmap_t, vaddr_t, pt_entry_t *, 1111static void pmap_l3pt_delref(pmap_t, vaddr_t, pt_entry_t *,
1112 struct pmap_tlb_context *); 1112 struct pmap_tlb_context *);
1113static void pmap_l2pt_delref(pmap_t, pt_entry_t *, pt_entry_t *, 1113static void pmap_l2pt_delref(pmap_t, pt_entry_t *, pt_entry_t *,
1114 struct pmap_tlb_context *); 1114 struct pmap_tlb_context *);
1115static void pmap_l1pt_delref(pmap_t, pt_entry_t *); 1115static void pmap_l1pt_delref(pmap_t, pt_entry_t *);
1116 1116
1117static void *pmap_l1pt_alloc(struct pool *, int); 1117static void *pmap_l1pt_alloc(struct pool *, int);
1118static void pmap_l1pt_free(struct pool *, void *); 1118static void pmap_l1pt_free(struct pool *, void *);
1119 1119
1120static struct pool_allocator pmap_l1pt_allocator = { 1120static struct pool_allocator pmap_l1pt_allocator = {
1121 pmap_l1pt_alloc, pmap_l1pt_free, 0, 1121 pmap_l1pt_alloc, pmap_l1pt_free, 0,
1122}; 1122};
1123 1123
1124static int pmap_l1pt_ctor(void *, void *, int); 1124static int pmap_l1pt_ctor(void *, void *, int);
1125 1125
1126/* 1126/*
1127 * PV table management functions. 1127 * PV table management functions.
1128 */ 1128 */
1129static int pmap_pv_enter(pmap_t, struct vm_page *, vaddr_t, pt_entry_t *, 1129static int pmap_pv_enter(pmap_t, struct vm_page *, vaddr_t, pt_entry_t *,
1130 bool, pv_entry_t); 1130 bool, pv_entry_t);
1131static void pmap_pv_remove(pmap_t, struct vm_page *, vaddr_t, bool, 1131static void pmap_pv_remove(pmap_t, struct vm_page *, vaddr_t, bool,
1132 pv_entry_t *); 1132 pv_entry_t *);
1133static void *pmap_pv_page_alloc(struct pool *, int); 1133static void *pmap_pv_page_alloc(struct pool *, int);
1134static void pmap_pv_page_free(struct pool *, void *); 1134static void pmap_pv_page_free(struct pool *, void *);
1135 1135
1136static struct pool_allocator pmap_pv_page_allocator = { 1136static struct pool_allocator pmap_pv_page_allocator = {
1137 pmap_pv_page_alloc, pmap_pv_page_free, 0, 1137 pmap_pv_page_alloc, pmap_pv_page_free, 0,
1138}; 1138};
1139 1139
1140#ifdef DEBUG 1140#ifdef DEBUG
1141void pmap_pv_dump(paddr_t); 1141void pmap_pv_dump(paddr_t);
1142#endif 1142#endif
1143 1143
1144#define pmap_pv_alloc() pool_cache_get(&pmap_pv_cache, PR_NOWAIT) 1144#define pmap_pv_alloc() pool_cache_get(&pmap_pv_cache, PR_NOWAIT)
1145#define pmap_pv_free(pv) pool_cache_put(&pmap_pv_cache, (pv)) 1145#define pmap_pv_free(pv) pool_cache_put(&pmap_pv_cache, (pv))
1146 1146
1147/* 1147/*
1148 * ASN management functions. 1148 * ASN management functions.
1149 */ 1149 */
1150static u_int pmap_asn_alloc(pmap_t, struct cpu_info *); 1150static u_int pmap_asn_alloc(pmap_t, struct cpu_info *);
1151 1151
1152/* 1152/*
1153 * Misc. functions. 1153 * Misc. functions.
1154 */ 1154 */
1155static bool pmap_physpage_alloc(int, paddr_t *); 1155static bool pmap_physpage_alloc(int, paddr_t *);
1156static void pmap_physpage_free(paddr_t); 1156static void pmap_physpage_free(paddr_t);
1157static int pmap_physpage_addref(void *); 1157static int pmap_physpage_addref(void *);
1158static int pmap_physpage_delref(void *); 1158static int pmap_physpage_delref(void *);
1159 1159
1160static bool vtophys_internal(vaddr_t, paddr_t *p); 1160static bool vtophys_internal(vaddr_t, paddr_t *p);
1161 1161
1162/* 1162/*
1163 * PMAP_KERNEL_PTE: 1163 * PMAP_KERNEL_PTE:
1164 * 1164 *
1165 * Get a kernel PTE. 1165 * Get a kernel PTE.
1166 * 1166 *
1167 * If debugging, do a table walk. If not debugging, just use 1167 * If debugging, do a table walk. If not debugging, just use
1168 * the Virtual Page Table, since all kernel page tables are 1168 * the Virtual Page Table, since all kernel page tables are
1169 * pre-allocated and mapped in. 1169 * pre-allocated and mapped in.
1170 */ 1170 */
1171#ifdef DEBUG 1171#ifdef DEBUG
1172#define PMAP_KERNEL_PTE(va) \ 1172#define PMAP_KERNEL_PTE(va) \
1173({ \ 1173({ \
1174 pt_entry_t *l1pte_, *l2pte_; \ 1174 pt_entry_t *l1pte_, *l2pte_; \
1175 \ 1175 \
1176 l1pte_ = pmap_l1pte(pmap_kernel(), va); \ 1176 l1pte_ = pmap_l1pte(pmap_kernel(), va); \
1177 if (pmap_pte_v(l1pte_) == 0) { \ 1177 if (pmap_pte_v(l1pte_) == 0) { \
1178 printf("kernel level 1 PTE not valid, va 0x%lx " \ 1178 printf("kernel level 1 PTE not valid, va 0x%lx " \
1179 "(line %d)\n", (va), __LINE__); \ 1179 "(line %d)\n", (va), __LINE__); \
1180 panic("PMAP_KERNEL_PTE"); \ 1180 panic("PMAP_KERNEL_PTE"); \
1181 } \ 1181 } \
1182 l2pte_ = pmap_l2pte(pmap_kernel(), va, l1pte_); \ 1182 l2pte_ = pmap_l2pte(pmap_kernel(), va, l1pte_); \
1183 if (pmap_pte_v(l2pte_) == 0) { \ 1183 if (pmap_pte_v(l2pte_) == 0) { \
1184 printf("kernel level 2 PTE not valid, va 0x%lx " \ 1184 printf("kernel level 2 PTE not valid, va 0x%lx " \
1185 "(line %d)\n", (va), __LINE__); \ 1185 "(line %d)\n", (va), __LINE__); \
1186 panic("PMAP_KERNEL_PTE"); \ 1186 panic("PMAP_KERNEL_PTE"); \
1187 } \ 1187 } \
1188 pmap_l3pte(pmap_kernel(), va, l2pte_); \ 1188 pmap_l3pte(pmap_kernel(), va, l2pte_); \
1189}) 1189})
1190#else 1190#else
1191#define PMAP_KERNEL_PTE(va) (&VPT[VPT_INDEX((va))]) 1191#define PMAP_KERNEL_PTE(va) (&VPT[VPT_INDEX((va))])
1192#endif 1192#endif
1193 1193
1194/* 1194/*
1195 * PMAP_STAT_{INCR,DECR}: 1195 * PMAP_STAT_{INCR,DECR}:
1196 * 1196 *
1197 * Increment or decrement a pmap statistic. 1197 * Increment or decrement a pmap statistic.
1198 */ 1198 */
1199#define PMAP_STAT_INCR(s, v) atomic_add_long((unsigned long *)(&(s)), (v)) 1199#define PMAP_STAT_INCR(s, v) atomic_add_long((unsigned long *)(&(s)), (v))
1200#define PMAP_STAT_DECR(s, v) atomic_add_long((unsigned long *)(&(s)), -(v)) 1200#define PMAP_STAT_DECR(s, v) atomic_add_long((unsigned long *)(&(s)), -(v))
1201 1201
1202/* 1202/*
1203 * pmap_init_cpu: 1203 * pmap_init_cpu:
1204 * 1204 *
1205 * Initilize pmap data in the cpu_info. 1205 * Initilize pmap data in the cpu_info.
1206 */ 1206 */
1207void 1207void
1208pmap_init_cpu(struct cpu_info * const ci) 1208pmap_init_cpu(struct cpu_info * const ci)
1209{ 1209{
1210 pmap_t const pmap = pmap_kernel(); 1210 pmap_t const pmap = pmap_kernel();
1211 1211
1212 /* All CPUs start out using the kernel pmap. */ 1212 /* All CPUs start out using the kernel pmap. */
1213 atomic_or_ulong(&pmap->pm_cpus, 1UL << ci->ci_cpuid); 1213 atomic_or_ulong(&pmap->pm_cpus, 1UL << ci->ci_cpuid);
1214 pmap_reference(pmap); 1214 pmap_reference(pmap);
1215 ci->ci_pmap = pmap; 1215 ci->ci_pmap = pmap;
1216 1216
1217 /* Initialize ASN allocation logic. */ 1217 /* Initialize ASN allocation logic. */
1218 ci->ci_next_asn = PMAP_ASN_FIRST_USER; 1218 ci->ci_next_asn = PMAP_ASN_FIRST_USER;
1219 ci->ci_asn_gen = PMAP_ASNGEN_INITIAL; 1219 ci->ci_asn_gen = PMAP_ASNGEN_INITIAL;
1220} 1220}
1221 1221
1222/* 1222/*
1223 * pmap_bootstrap: 1223 * pmap_bootstrap:
1224 * 1224 *
1225 * Bootstrap the system to run with virtual memory. 1225 * Bootstrap the system to run with virtual memory.
1226 * 1226 *
1227 * Note: no locking is necessary in this function. 1227 * Note: no locking is necessary in this function.
1228 */ 1228 */
1229void 1229void
1230pmap_bootstrap(paddr_t ptaddr, u_int maxasn, u_long ncpuids) 1230pmap_bootstrap(paddr_t ptaddr, u_int maxasn, u_long ncpuids)
1231{ 1231{
1232 vsize_t lev2mapsize, lev3mapsize; 1232 vsize_t lev2mapsize, lev3mapsize;
1233 pt_entry_t *lev2map, *lev3map; 1233 pt_entry_t *lev2map, *lev3map;
1234 pt_entry_t pte; 1234 pt_entry_t pte;
1235 vsize_t bufsz; 1235 vsize_t bufsz;
1236 struct pcb *pcb; 1236 struct pcb *pcb;
1237 int i; 1237 int i;
1238 1238
1239#ifdef DEBUG 1239#ifdef DEBUG
1240 if (pmapdebug & (PDB_FOLLOW|PDB_BOOTSTRAP)) 1240 if (pmapdebug & (PDB_FOLLOW|PDB_BOOTSTRAP))
1241 printf("pmap_bootstrap(0x%lx, %u)\n", ptaddr, maxasn); 1241 printf("pmap_bootstrap(0x%lx, %u)\n", ptaddr, maxasn);
1242#endif 1242#endif
1243 1243
1244 /* 1244 /*
1245 * Compute the number of pages kmem_arena will have. 1245 * Compute the number of pages kmem_arena will have.
1246 */ 1246 */
1247 kmeminit_nkmempages(); 1247 kmeminit_nkmempages();
1248 1248
1249 /* 1249 /*
1250 * Figure out how many initial PTE's are necessary to map the 1250 * Figure out how many initial PTE's are necessary to map the
1251 * kernel. We also reserve space for kmem_alloc_pageable() 1251 * kernel. We also reserve space for kmem_alloc_pageable()
1252 * for vm_fork(). 1252 * for vm_fork().
1253 */ 1253 */
1254 1254
1255 /* Get size of buffer cache and set an upper limit */ 1255 /* Get size of buffer cache and set an upper limit */
1256 bufsz = buf_memcalc(); 1256 bufsz = buf_memcalc();
1257 buf_setvalimit(bufsz); 1257 buf_setvalimit(bufsz);
1258 1258
1259 lev3mapsize = 1259 lev3mapsize =
1260 (VM_PHYS_SIZE + (ubc_nwins << ubc_winshift) + 1260 (VM_PHYS_SIZE + (ubc_nwins << ubc_winshift) +
1261 bufsz + 16 * NCARGS + pager_map_size) / PAGE_SIZE + 1261 bufsz + 16 * NCARGS + pager_map_size) / PAGE_SIZE +
1262 (maxproc * UPAGES) + nkmempages; 1262 (maxproc * UPAGES) + nkmempages;
1263 1263
1264 lev3mapsize = roundup(lev3mapsize, NPTEPG); 1264 lev3mapsize = roundup(lev3mapsize, NPTEPG);
1265 1265
1266 /* 1266 /*
1267 * Initialize `FYI' variables. Note we're relying on 1267 * Initialize `FYI' variables. Note we're relying on
1268 * the fact that BSEARCH sorts the vm_physmem[] array 1268 * the fact that BSEARCH sorts the vm_physmem[] array
1269 * for us. 1269 * for us.
1270 */ 1270 */
1271 avail_start = ptoa(uvm_physseg_get_avail_start(uvm_physseg_get_first())); 1271 avail_start = ptoa(uvm_physseg_get_avail_start(uvm_physseg_get_first()));
1272 avail_end = ptoa(uvm_physseg_get_avail_end(uvm_physseg_get_last())); 1272 avail_end = ptoa(uvm_physseg_get_avail_end(uvm_physseg_get_last()));
1273 virtual_end = VM_MIN_KERNEL_ADDRESS + lev3mapsize * PAGE_SIZE; 1273 virtual_end = VM_MIN_KERNEL_ADDRESS + lev3mapsize * PAGE_SIZE;
1274 1274
1275#if 0 1275#if 0
1276 printf("avail_start = 0x%lx\n", avail_start); 1276 printf("avail_start = 0x%lx\n", avail_start);
1277 printf("avail_end = 0x%lx\n", avail_end); 1277 printf("avail_end = 0x%lx\n", avail_end);
1278 printf("virtual_end = 0x%lx\n", virtual_end); 1278 printf("virtual_end = 0x%lx\n", virtual_end);
1279#endif 1279#endif
1280 1280
1281 /* 1281 /*
1282 * Allocate a level 1 PTE table for the kernel. 1282 * Allocate a level 1 PTE table for the kernel.
1283 * This is always one page long. 1283 * This is always one page long.
1284 * IF THIS IS NOT A MULTIPLE OF PAGE_SIZE, ALL WILL GO TO HELL. 1284 * IF THIS IS NOT A MULTIPLE OF PAGE_SIZE, ALL WILL GO TO HELL.
1285 */ 1285 */
1286 kernel_lev1map = (pt_entry_t *) 1286 kernel_lev1map = (pt_entry_t *)
1287 uvm_pageboot_alloc(sizeof(pt_entry_t) * NPTEPG); 1287 uvm_pageboot_alloc(sizeof(pt_entry_t) * NPTEPG);
1288 1288
1289 /* 1289 /*
1290 * Allocate a level 2 PTE table for the kernel. 1290 * Allocate a level 2 PTE table for the kernel.
1291 * These must map all of the level3 PTEs. 1291 * These must map all of the level3 PTEs.
1292 * IF THIS IS NOT A MULTIPLE OF PAGE_SIZE, ALL WILL GO TO HELL. 1292 * IF THIS IS NOT A MULTIPLE OF PAGE_SIZE, ALL WILL GO TO HELL.
1293 */ 1293 */
1294 lev2mapsize = roundup(howmany(lev3mapsize, NPTEPG), NPTEPG); 1294 lev2mapsize = roundup(howmany(lev3mapsize, NPTEPG), NPTEPG);
1295 lev2map = (pt_entry_t *) 1295 lev2map = (pt_entry_t *)
1296 uvm_pageboot_alloc(sizeof(pt_entry_t) * lev2mapsize); 1296 uvm_pageboot_alloc(sizeof(pt_entry_t) * lev2mapsize);
1297 1297
1298 /* 1298 /*
1299 * Allocate a level 3 PTE table for the kernel. 1299 * Allocate a level 3 PTE table for the kernel.
1300 * Contains lev3mapsize PTEs. 1300 * Contains lev3mapsize PTEs.
1301 */ 1301 */
1302 lev3map = (pt_entry_t *) 1302 lev3map = (pt_entry_t *)
1303 uvm_pageboot_alloc(sizeof(pt_entry_t) * lev3mapsize); 1303 uvm_pageboot_alloc(sizeof(pt_entry_t) * lev3mapsize);
1304 1304
1305 /* 1305 /*
1306 * Set up level 1 page table 1306 * Set up level 1 page table
1307 */ 1307 */
1308 1308
1309 /* Map all of the level 2 pte pages */ 1309 /* Map all of the level 2 pte pages */
1310 for (i = 0; i < howmany(lev2mapsize, NPTEPG); i++) { 1310 for (i = 0; i < howmany(lev2mapsize, NPTEPG); i++) {
1311 pte = (ALPHA_K0SEG_TO_PHYS(((vaddr_t)lev2map) + 1311 pte = (ALPHA_K0SEG_TO_PHYS(((vaddr_t)lev2map) +
1312 (i*PAGE_SIZE)) >> PGSHIFT) << PG_SHIFT; 1312 (i*PAGE_SIZE)) >> PGSHIFT) << PG_SHIFT;
1313 pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED; 1313 pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;
1314 kernel_lev1map[l1pte_index(VM_MIN_KERNEL_ADDRESS + 1314 kernel_lev1map[l1pte_index(VM_MIN_KERNEL_ADDRESS +
1315 (i*PAGE_SIZE*NPTEPG*NPTEPG))] = pte; 1315 (i*PAGE_SIZE*NPTEPG*NPTEPG))] = pte;
1316 } 1316 }
1317 1317
1318 /* Map the virtual page table */ 1318 /* Map the virtual page table */
1319 pte = (ALPHA_K0SEG_TO_PHYS((vaddr_t)kernel_lev1map) >> PGSHIFT) 1319 pte = (ALPHA_K0SEG_TO_PHYS((vaddr_t)kernel_lev1map) >> PGSHIFT)
1320 << PG_SHIFT; 1320 << PG_SHIFT;
1321 pte |= PG_V | PG_KRE | PG_KWE; /* NOTE NO ASM */ 1321 pte |= PG_V | PG_KRE | PG_KWE; /* NOTE NO ASM */
1322 kernel_lev1map[l1pte_index(VPTBASE)] = pte; 1322 kernel_lev1map[l1pte_index(VPTBASE)] = pte;
1323 VPT = (pt_entry_t *)VPTBASE; 1323 VPT = (pt_entry_t *)VPTBASE;
1324 1324
1325 /* 1325 /*
1326 * Set up level 2 page table. 1326 * Set up level 2 page table.
1327 */ 1327 */
1328 /* Map all of the level 3 pte pages */ 1328 /* Map all of the level 3 pte pages */
1329 for (i = 0; i < howmany(lev3mapsize, NPTEPG); i++) { 1329 for (i = 0; i < howmany(lev3mapsize, NPTEPG); i++) {
1330 pte = (ALPHA_K0SEG_TO_PHYS(((vaddr_t)lev3map) + 1330 pte = (ALPHA_K0SEG_TO_PHYS(((vaddr_t)lev3map) +
1331 (i*PAGE_SIZE)) >> PGSHIFT) << PG_SHIFT; 1331 (i*PAGE_SIZE)) >> PGSHIFT) << PG_SHIFT;
1332 pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED; 1332 pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;
1333 lev2map[l2pte_index(VM_MIN_KERNEL_ADDRESS+ 1333 lev2map[l2pte_index(VM_MIN_KERNEL_ADDRESS+
1334 (i*PAGE_SIZE*NPTEPG))] = pte; 1334 (i*PAGE_SIZE*NPTEPG))] = pte;
1335 } 1335 }
1336 1336
1337 /* Initialize the pmap_growkernel_lock. */ 1337 /* Initialize the pmap_growkernel_lock. */
1338 rw_init(&pmap_growkernel_lock); 1338 rw_init(&pmap_growkernel_lock);
1339 1339
1340 /* 1340 /*
1341 * Set up level three page table (lev3map) 1341 * Set up level three page table (lev3map)
1342 */ 1342 */
1343 /* Nothing to do; it's already zero'd */ 1343 /* Nothing to do; it's already zero'd */
1344 1344
1345 /* 1345 /*
1346 * Initialize the pmap pools and list. 1346 * Initialize the pmap pools and list.
1347 */ 1347 */
1348 pmap_ncpuids = ncpuids; 1348 pmap_ncpuids = ncpuids;
1349 pool_cache_bootstrap(&pmap_pmap_cache, PMAP_SIZEOF(pmap_ncpuids), 1349 pool_cache_bootstrap(&pmap_pmap_cache, PMAP_SIZEOF(pmap_ncpuids),
1350 COHERENCY_UNIT, 0, 0, "pmap", NULL, IPL_NONE, NULL, NULL, NULL); 1350 COHERENCY_UNIT, 0, 0, "pmap", NULL, IPL_NONE, NULL, NULL, NULL);
1351 pool_cache_bootstrap(&pmap_l1pt_cache, PAGE_SIZE, 0, 0, 0, "pmapl1pt", 1351 pool_cache_bootstrap(&pmap_l1pt_cache, PAGE_SIZE, 0, 0, 0, "pmapl1pt",
1352 &pmap_l1pt_allocator, IPL_NONE, pmap_l1pt_ctor, NULL, NULL); 1352 &pmap_l1pt_allocator, IPL_NONE, pmap_l1pt_ctor, NULL, NULL);
1353 pool_cache_bootstrap(&pmap_pv_cache, sizeof(struct pv_entry), 0, 0, 1353 pool_cache_bootstrap(&pmap_pv_cache, sizeof(struct pv_entry), 0, 0,
1354 PR_LARGECACHE, "pmappv", &pmap_pv_page_allocator, IPL_NONE, NULL, 1354 PR_LARGECACHE, "pmappv", &pmap_pv_page_allocator, IPL_NONE, NULL,
1355 NULL, NULL); 1355 NULL, NULL);
1356 1356
1357 TAILQ_INIT(&pmap_all_pmaps); 1357 TAILQ_INIT(&pmap_all_pmaps);
1358 1358
1359 /* Initialize the ASN logic. See also pmap_init_cpu(). */ 1359 /* Initialize the ASN logic. See also pmap_init_cpu(). */
1360 pmap_max_asn = maxasn; 1360 pmap_max_asn = maxasn;
1361 1361
1362 /* 1362 /*
1363 * Initialize the locks. 1363 * Initialize the locks.
1364 */ 1364 */
1365 rw_init(&pmap_main_lock); 1365 rw_init(&pmap_main_lock);
1366 mutex_init(&pmap_all_pmaps_lock, MUTEX_DEFAULT, IPL_NONE); 1366 mutex_init(&pmap_all_pmaps_lock, MUTEX_DEFAULT, IPL_NONE);
1367 for (i = 0; i < __arraycount(pmap_pvh_locks); i++) { 1367 for (i = 0; i < __arraycount(pmap_pvh_locks); i++) {
1368 mutex_init(&pmap_pvh_locks[i].lock, MUTEX_DEFAULT, IPL_NONE); 1368 mutex_init(&pmap_pvh_locks[i].lock, MUTEX_DEFAULT, IPL_NONE);
1369 } 1369 }
1370 for (i = 0; i < __arraycount(pmap_pvh_locks); i++) { 1370 for (i = 0; i < __arraycount(pmap_pvh_locks); i++) {
1371 mutex_init(&pmap_pmap_locks[i].locks.lock, 1371 mutex_init(&pmap_pmap_locks[i].locks.lock,
1372 MUTEX_DEFAULT, IPL_NONE); 1372 MUTEX_DEFAULT, IPL_NONE);
1373 mutex_init(&pmap_pmap_locks[i].locks.activation_lock, 1373 mutex_init(&pmap_pmap_locks[i].locks.activation_lock,
1374 MUTEX_SPIN, IPL_SCHED); 1374 MUTEX_SPIN, IPL_SCHED);
1375 } 1375 }
1376  1376
1377 /* 1377 /*
1378 * This must block any interrupt from which a TLB shootdown 1378 * This must block any interrupt from which a TLB shootdown
1379 * could be issued, but must NOT block IPIs. 1379 * could be issued, but must NOT block IPIs.
1380 */ 1380 */
1381 mutex_init(&tlb_lock, MUTEX_SPIN, IPL_VM); 1381 mutex_init(&tlb_lock, MUTEX_SPIN, IPL_VM);
1382 1382
1383 /* 1383 /*
1384 * Initialize kernel pmap. Note that all kernel mappings 1384 * Initialize kernel pmap. Note that all kernel mappings
1385 * have PG_ASM set, so the ASN doesn't really matter for 1385 * have PG_ASM set, so the ASN doesn't really matter for
1386 * the kernel pmap. Also, since the kernel pmap always 1386 * the kernel pmap. Also, since the kernel pmap always
1387 * references kernel_lev1map, it always has an invalid ASN 1387 * references kernel_lev1map, it always has an invalid ASN
1388 * generation. 1388 * generation.
1389 */ 1389 */
1390 memset(pmap_kernel(), 0, sizeof(struct pmap)); 1390 memset(pmap_kernel(), 0, sizeof(struct pmap));
1391 pmap_kernel()->pm_lev1map = kernel_lev1map; 1391 pmap_kernel()->pm_lev1map = kernel_lev1map;
1392 atomic_store_relaxed(&pmap_kernel()->pm_count, 1); 1392 atomic_store_relaxed(&pmap_kernel()->pm_count, 1);
1393 /* Kernel pmap does not have ASN info. */ 1393 /* Kernel pmap does not have ASN info. */
1394 TAILQ_INSERT_TAIL(&pmap_all_pmaps, pmap_kernel(), pm_list); 1394 TAILQ_INSERT_TAIL(&pmap_all_pmaps, pmap_kernel(), pm_list);
1395 1395
1396 /* 1396 /*
1397 * Set up lwp0's PCB such that the ptbr points to the right place 1397 * Set up lwp0's PCB such that the ptbr points to the right place
1398 * and has the kernel pmap's (really unused) ASN. 1398 * and has the kernel pmap's (really unused) ASN.
1399 */ 1399 */
1400 pcb = lwp_getpcb(&lwp0); 1400 pcb = lwp_getpcb(&lwp0);
1401 pcb->pcb_hw.apcb_ptbr = 1401 pcb->pcb_hw.apcb_ptbr =
1402 ALPHA_K0SEG_TO_PHYS((vaddr_t)kernel_lev1map) >> PGSHIFT; 1402 ALPHA_K0SEG_TO_PHYS((vaddr_t)kernel_lev1map) >> PGSHIFT;
1403 pcb->pcb_hw.apcb_asn = PMAP_ASN_KERNEL; 1403 pcb->pcb_hw.apcb_asn = PMAP_ASN_KERNEL;
1404 1404
1405 struct cpu_info * const ci = curcpu(); 1405 struct cpu_info * const ci = curcpu();
1406 pmap_init_cpu(ci); 1406 pmap_init_cpu(ci);
1407} 1407}
1408 1408
1409/* 1409/*
1410 * pmap_virtual_space: [ INTERFACE ] 1410 * pmap_virtual_space: [ INTERFACE ]
1411 * 1411 *
1412 * Define the initial bounds of the kernel virtual address space. 1412 * Define the initial bounds of the kernel virtual address space.
1413 */ 1413 */
1414void 1414void
1415pmap_virtual_space(vaddr_t *vstartp, vaddr_t *vendp) 1415pmap_virtual_space(vaddr_t *vstartp, vaddr_t *vendp)
1416{ 1416{
1417 1417
1418 *vstartp = VM_MIN_KERNEL_ADDRESS; /* kernel is in K0SEG */ 1418 *vstartp = VM_MIN_KERNEL_ADDRESS; /* kernel is in K0SEG */
1419 *vendp = VM_MAX_KERNEL_ADDRESS; /* we use pmap_growkernel */ 1419 *vendp = VM_MAX_KERNEL_ADDRESS; /* we use pmap_growkernel */
1420} 1420}
1421 1421
1422/* 1422/*
1423 * pmap_steal_memory: [ INTERFACE ] 1423 * pmap_steal_memory: [ INTERFACE ]
1424 * 1424 *
1425 * Bootstrap memory allocator (alternative to vm_bootstrap_steal_memory()). 1425 * Bootstrap memory allocator (alternative to vm_bootstrap_steal_memory()).
1426 * This function allows for early dynamic memory allocation until the 1426 * This function allows for early dynamic memory allocation until the
1427 * virtual memory system has been bootstrapped. After that point, either 1427 * virtual memory system has been bootstrapped. After that point, either
1428 * kmem_alloc or malloc should be used. This function works by stealing 1428 * kmem_alloc or malloc should be used. This function works by stealing
1429 * pages from the (to be) managed page pool, then implicitly mapping the 1429 * pages from the (to be) managed page pool, then implicitly mapping the
1430 * pages (by using their k0seg addresses) and zeroing them. 1430 * pages (by using their k0seg addresses) and zeroing them.
1431 * 1431 *
1432 * It may be used once the physical memory segments have been pre-loaded 1432 * It may be used once the physical memory segments have been pre-loaded
1433 * into the vm_physmem[] array. Early memory allocation MUST use this 1433 * into the vm_physmem[] array. Early memory allocation MUST use this
1434 * interface! This cannot be used after vm_page_startup(), and will 1434 * interface! This cannot be used after vm_page_startup(), and will
1435 * generate a panic if tried. 1435 * generate a panic if tried.
1436 * 1436 *
1437 * Note that this memory will never be freed, and in essence it is wired 1437 * Note that this memory will never be freed, and in essence it is wired
1438 * down. 1438 * down.
1439 * 1439 *
1440 * We must adjust *vstartp and/or *vendp iff we use address space 1440 * We must adjust *vstartp and/or *vendp iff we use address space
1441 * from the kernel virtual address range defined by pmap_virtual_space(). 1441 * from the kernel virtual address range defined by pmap_virtual_space().
1442 * 1442 *
1443 * Note: no locking is necessary in this function. 1443 * Note: no locking is necessary in this function.
1444 */ 1444 */
1445vaddr_t 1445vaddr_t
1446pmap_steal_memory(vsize_t size, vaddr_t *vstartp, vaddr_t *vendp) 1446pmap_steal_memory(vsize_t size, vaddr_t *vstartp, vaddr_t *vendp)
1447{ 1447{
1448 int npgs; 1448 int npgs;
1449 vaddr_t va; 1449 vaddr_t va;
1450 paddr_t pa; 1450 paddr_t pa;
1451 1451
1452 uvm_physseg_t bank; 1452 uvm_physseg_t bank;
1453 1453
1454 size = round_page(size); 1454 size = round_page(size);
1455 npgs = atop(size); 1455 npgs = atop(size);
1456 1456
1457#if 0 1457#if 0
1458 printf("PSM: size 0x%lx (npgs 0x%x)\n", size, npgs); 1458 printf("PSM: size 0x%lx (npgs 0x%x)\n", size, npgs);
1459#endif 1459#endif
1460 1460
1461 for (bank = uvm_physseg_get_first(); 1461 for (bank = uvm_physseg_get_first();
1462 uvm_physseg_valid_p(bank); 1462 uvm_physseg_valid_p(bank);
1463 bank = uvm_physseg_get_next(bank)) { 1463 bank = uvm_physseg_get_next(bank)) {
1464 if (uvm.page_init_done == true) 1464 if (uvm.page_init_done == true)
1465 panic("pmap_steal_memory: called _after_ bootstrap"); 1465 panic("pmap_steal_memory: called _after_ bootstrap");
1466 1466
1467#if 0 1467#if 0
1468 printf(" bank %d: avail_start 0x%"PRIxPADDR", start 0x%"PRIxPADDR", " 1468 printf(" bank %d: avail_start 0x%"PRIxPADDR", start 0x%"PRIxPADDR", "
1469 "avail_end 0x%"PRIxPADDR"\n", bank, uvm_physseg_get_avail_start(bank), 1469 "avail_end 0x%"PRIxPADDR"\n", bank, uvm_physseg_get_avail_start(bank),
1470 uvm_physseg_get_start(bank), uvm_physseg_get_avail_end(bank)); 1470 uvm_physseg_get_start(bank), uvm_physseg_get_avail_end(bank));
1471#endif 1471#endif
1472 1472
1473 if (uvm_physseg_get_avail_start(bank) != uvm_physseg_get_start(bank) || 1473 if (uvm_physseg_get_avail_start(bank) != uvm_physseg_get_start(bank) ||
1474 uvm_physseg_get_avail_start(bank) >= uvm_physseg_get_avail_end(bank)) 1474 uvm_physseg_get_avail_start(bank) >= uvm_physseg_get_avail_end(bank))
1475 continue; 1475 continue;
1476 1476
1477#if 0 1477#if 0
1478 printf(" avail_end - avail_start = 0x%"PRIxPADDR"\n", 1478 printf(" avail_end - avail_start = 0x%"PRIxPADDR"\n",
1479 uvm_physseg_get_avail_end(bank) - uvm_physseg_get_avail_start(bank)); 1479 uvm_physseg_get_avail_end(bank) - uvm_physseg_get_avail_start(bank));
1480#endif 1480#endif
1481 1481
1482 if (uvm_physseg_get_avail_end(bank) - uvm_physseg_get_avail_start(bank) 1482 if (uvm_physseg_get_avail_end(bank) - uvm_physseg_get_avail_start(bank)
1483 < npgs) 1483 < npgs)
1484 continue; 1484 continue;
1485 1485
1486 /* 1486 /*
1487 * There are enough pages here; steal them! 1487 * There are enough pages here; steal them!
1488 */ 1488 */
1489 pa = ptoa(uvm_physseg_get_start(bank)); 1489 pa = ptoa(uvm_physseg_get_start(bank));
1490 uvm_physseg_unplug(atop(pa), npgs); 1490 uvm_physseg_unplug(atop(pa), npgs);
1491 1491
1492 va = ALPHA_PHYS_TO_K0SEG(pa); 1492 va = ALPHA_PHYS_TO_K0SEG(pa);
1493 memset((void *)va, 0, size); 1493 memset((void *)va, 0, size);
1494 pmap_pages_stolen += npgs; 1494 pmap_pages_stolen += npgs;
1495 return (va); 1495 return (va);
1496 } 1496 }
1497 1497
1498 /* 1498 /*
1499 * If we got here, this was no memory left. 1499 * If we got here, this was no memory left.
1500 */ 1500 */
1501 panic("pmap_steal_memory: no memory to steal"); 1501 panic("pmap_steal_memory: no memory to steal");
1502} 1502}
1503 1503
1504/* 1504/*
1505 * pmap_init: [ INTERFACE ] 1505 * pmap_init: [ INTERFACE ]
1506 * 1506 *
1507 * Initialize the pmap module. Called by vm_init(), to initialize any 1507 * Initialize the pmap module. Called by vm_init(), to initialize any
1508 * structures that the pmap system needs to map virtual memory. 1508 * structures that the pmap system needs to map virtual memory.
1509 * 1509 *
1510 * Note: no locking is necessary in this function. 1510 * Note: no locking is necessary in this function.
1511 */ 1511 */
1512void 1512void
1513pmap_init(void) 1513pmap_init(void)
1514{ 1514{
1515 1515
1516#ifdef DEBUG 1516#ifdef DEBUG
1517 if (pmapdebug & PDB_FOLLOW) 1517 if (pmapdebug & PDB_FOLLOW)
1518 printf("pmap_init()\n"); 1518 printf("pmap_init()\n");
1519#endif 1519#endif
1520 1520
1521 /* initialize protection array */ 1521 /* initialize protection array */
1522 alpha_protection_init(); 1522 alpha_protection_init();
1523 1523
1524 /* Initialize TLB handling. */ 1524 /* Initialize TLB handling. */
1525 pmap_tlb_init(); 1525 pmap_tlb_init();
1526 1526
1527 /* 1527 /*
1528 * Set a low water mark on the pv_entry pool, so that we are 1528 * Set a low water mark on the pv_entry pool, so that we are
1529 * more likely to have these around even in extreme memory 1529 * more likely to have these around even in extreme memory
1530 * starvation. 1530 * starvation.
1531 */ 1531 */
1532 pool_cache_setlowat(&pmap_pv_cache, pmap_pv_lowat); 1532 pool_cache_setlowat(&pmap_pv_cache, pmap_pv_lowat);
1533 1533
1534 /* 1534 /*
1535 * Now it is safe to enable pv entry recording. 1535 * Now it is safe to enable pv entry recording.
1536 */ 1536 */
1537 pmap_initialized = true; 1537 pmap_initialized = true;
1538 1538
1539#if 0 1539#if 0
1540 for (uvm_physseg_t bank = uvm_physseg_get_first(); 1540 for (uvm_physseg_t bank = uvm_physseg_get_first();
1541 uvm_physseg_valid_p(bank); 1541 uvm_physseg_valid_p(bank);
1542 bank = uvm_physseg_get_next(bank)) { 1542 bank = uvm_physseg_get_next(bank)) {
1543 printf("bank %d\n", bank); 1543 printf("bank %d\n", bank);
1544 printf("\tstart = 0x%lx\n", ptoa(uvm_physseg_get_start(bank))); 1544 printf("\tstart = 0x%lx\n", ptoa(uvm_physseg_get_start(bank)));
1545 printf("\tend = 0x%lx\n", ptoa(uvm_physseg_get_end(bank))); 1545 printf("\tend = 0x%lx\n", ptoa(uvm_physseg_get_end(bank)));
1546 printf("\tavail_start = 0x%lx\n", 1546 printf("\tavail_start = 0x%lx\n",
1547 ptoa(uvm_physseg_get_avail_start(bank))); 1547 ptoa(uvm_physseg_get_avail_start(bank)));
1548 printf("\tavail_end = 0x%lx\n", 1548 printf("\tavail_end = 0x%lx\n",
1549 ptoa(uvm_physseg_get_avail_end(bank))); 1549 ptoa(uvm_physseg_get_avail_end(bank)));
1550 } 1550 }
1551#endif 1551#endif
1552} 1552}
1553 1553
1554/* 1554/*
1555 * pmap_create: [ INTERFACE ] 1555 * pmap_create: [ INTERFACE ]
1556 * 1556 *
1557 * Create and return a physical map. 1557 * Create and return a physical map.
1558 * 1558 *
1559 * Note: no locking is necessary in this function. 1559 * Note: no locking is necessary in this function.
1560 */ 1560 */
1561pmap_t 1561pmap_t
1562pmap_create(void) 1562pmap_create(void)
1563{ 1563{
1564 pmap_t pmap; 1564 pmap_t pmap;
1565 int i; 1565 int i;
1566 1566
1567#ifdef DEBUG 1567#ifdef DEBUG
1568 if (pmapdebug & (PDB_FOLLOW|PDB_CREATE)) 1568 if (pmapdebug & (PDB_FOLLOW|PDB_CREATE))
1569 printf("pmap_create()\n"); 1569 printf("pmap_create()\n");
1570#endif 1570#endif
1571 1571
1572 pmap = pool_cache_get(&pmap_pmap_cache, PR_WAITOK); 1572 pmap = pool_cache_get(&pmap_pmap_cache, PR_WAITOK);
1573 memset(pmap, 0, sizeof(*pmap)); 1573 memset(pmap, 0, sizeof(*pmap));
1574 1574
1575 atomic_store_relaxed(&pmap->pm_count, 1); 1575 atomic_store_relaxed(&pmap->pm_count, 1);
1576 1576
1577 /* 1577 /*
1578 * There are only kernel mappings at this point; give the pmap 1578 * There are only kernel mappings at this point; give the pmap
1579 * the kernel ASN. This will be initialized to correct values 1579 * the kernel ASN. This will be initialized to correct values
1580 * when the pmap is activated. 1580 * when the pmap is activated.
1581 */ 1581 */
1582 for (i = 0; i < pmap_ncpuids; i++) { 1582 for (i = 0; i < pmap_ncpuids; i++) {
1583 pmap->pm_asni[i].pma_asn = PMAP_ASN_KERNEL; 1583 pmap->pm_percpu[i].pmc_asn = PMAP_ASN_KERNEL;
1584 pmap->pm_asni[i].pma_asngen = PMAP_ASNGEN_INVALID; 1584 pmap->pm_percpu[i].pmc_asngen = PMAP_ASNGEN_INVALID;
1585 } 1585 }
1586 1586
1587 try_again: 1587 try_again:
1588 rw_enter(&pmap_growkernel_lock, RW_READER); 1588 rw_enter(&pmap_growkernel_lock, RW_READER);
1589 1589
1590 pmap->pm_lev1map = pool_cache_get(&pmap_l1pt_cache, PR_NOWAIT); 1590 pmap->pm_lev1map = pool_cache_get(&pmap_l1pt_cache, PR_NOWAIT);
1591 if (__predict_false(pmap->pm_lev1map == NULL)) { 1591 if (__predict_false(pmap->pm_lev1map == NULL)) {
1592 rw_exit(&pmap_growkernel_lock); 1592 rw_exit(&pmap_growkernel_lock);
1593 (void) kpause("pmap_create", false, hz >> 2, NULL); 1593 (void) kpause("pmap_create", false, hz >> 2, NULL);
1594 goto try_again; 1594 goto try_again;
1595 } 1595 }
1596 1596
1597 mutex_enter(&pmap_all_pmaps_lock); 1597 mutex_enter(&pmap_all_pmaps_lock);
1598 TAILQ_INSERT_TAIL(&pmap_all_pmaps, pmap, pm_list); 1598 TAILQ_INSERT_TAIL(&pmap_all_pmaps, pmap, pm_list);
1599 mutex_exit(&pmap_all_pmaps_lock); 1599 mutex_exit(&pmap_all_pmaps_lock);
1600 1600
1601 rw_exit(&pmap_growkernel_lock); 1601 rw_exit(&pmap_growkernel_lock);
1602 1602
1603 return (pmap); 1603 return (pmap);
1604} 1604}
1605 1605
1606/* 1606/*
1607 * pmap_destroy: [ INTERFACE ] 1607 * pmap_destroy: [ INTERFACE ]
1608 * 1608 *
1609 * Drop the reference count on the specified pmap, releasing 1609 * Drop the reference count on the specified pmap, releasing
1610 * all resources if the reference count drops to zero. 1610 * all resources if the reference count drops to zero.
1611 */ 1611 */
1612void 1612void
1613pmap_destroy(pmap_t pmap) 1613pmap_destroy(pmap_t pmap)
1614{ 1614{
1615 1615
1616#ifdef DEBUG 1616#ifdef DEBUG
1617 if (pmapdebug & PDB_FOLLOW) 1617 if (pmapdebug & PDB_FOLLOW)
1618 printf("pmap_destroy(%p)\n", pmap); 1618 printf("pmap_destroy(%p)\n", pmap);
1619#endif 1619#endif
1620 1620
1621 PMAP_MP(membar_exit()); 1621 PMAP_MP(membar_exit());
1622 KASSERT(atomic_load_relaxed(&pmap->pm_count) > 0); 1622 KASSERT(atomic_load_relaxed(&pmap->pm_count) > 0);
1623 if (atomic_dec_uint_nv(&pmap->pm_count) > 0) 1623 if (atomic_dec_uint_nv(&pmap->pm_count) > 0)
1624 return; 1624 return;
1625 1625
1626 rw_enter(&pmap_growkernel_lock, RW_READER); 1626 rw_enter(&pmap_growkernel_lock, RW_READER);
1627 1627
1628 /* 1628 /*
1629 * Remove it from the global list of all pmaps. 1629 * Remove it from the global list of all pmaps.
1630 */ 1630 */
1631 mutex_enter(&pmap_all_pmaps_lock); 1631 mutex_enter(&pmap_all_pmaps_lock);
1632 TAILQ_REMOVE(&pmap_all_pmaps, pmap, pm_list); 1632 TAILQ_REMOVE(&pmap_all_pmaps, pmap, pm_list);
1633 mutex_exit(&pmap_all_pmaps_lock); 1633 mutex_exit(&pmap_all_pmaps_lock);
1634 1634
1635 pool_cache_put(&pmap_l1pt_cache, pmap->pm_lev1map); 1635 pool_cache_put(&pmap_l1pt_cache, pmap->pm_lev1map);
1636 pmap->pm_lev1map = (pt_entry_t *)0xdeadbeefUL; 1636 pmap->pm_lev1map = (pt_entry_t *)0xdeadbeefUL;
1637 1637
1638 rw_exit(&pmap_growkernel_lock); 1638 rw_exit(&pmap_growkernel_lock);
1639 1639
1640 pool_cache_put(&pmap_pmap_cache, pmap); 1640 pool_cache_put(&pmap_pmap_cache, pmap);
1641} 1641}
1642 1642
1643/* 1643/*
1644 * pmap_reference: [ INTERFACE ] 1644 * pmap_reference: [ INTERFACE ]
1645 * 1645 *
1646 * Add a reference to the specified pmap. 1646 * Add a reference to the specified pmap.
1647 */ 1647 */
1648void 1648void
1649pmap_reference(pmap_t pmap) 1649pmap_reference(pmap_t pmap)
1650{ 1650{
1651 unsigned int newcount __diagused; 1651 unsigned int newcount __diagused;
1652 1652
1653#ifdef DEBUG 1653#ifdef DEBUG
1654 if (pmapdebug & PDB_FOLLOW) 1654 if (pmapdebug & PDB_FOLLOW)
1655 printf("pmap_reference(%p)\n", pmap); 1655 printf("pmap_reference(%p)\n", pmap);
1656#endif 1656#endif
1657 1657
1658 newcount = atomic_inc_uint_nv(&pmap->pm_count); 1658 newcount = atomic_inc_uint_nv(&pmap->pm_count);
1659 KASSERT(newcount != 0); 1659 KASSERT(newcount != 0);
1660 PMAP_MP(membar_enter()); 1660 PMAP_MP(membar_enter());
1661} 1661}
1662 1662
1663/* 1663/*
1664 * pmap_remove: [ INTERFACE ] 1664 * pmap_remove: [ INTERFACE ]
1665 * 1665 *
1666 * Remove the given range of addresses from the specified map. 1666 * Remove the given range of addresses from the specified map.
1667 * 1667 *
1668 * It is assumed that the start and end are properly 1668 * It is assumed that the start and end are properly
1669 * rounded to the page size. 1669 * rounded to the page size.
1670 */ 1670 */
1671static void 1671static void
1672pmap_remove_internal(pmap_t pmap, vaddr_t sva, vaddr_t eva, 1672pmap_remove_internal(pmap_t pmap, vaddr_t sva, vaddr_t eva,
1673 struct pmap_tlb_context * const tlbctx) 1673 struct pmap_tlb_context * const tlbctx)
1674{ 1674{
1675 pt_entry_t *l1pte, *l2pte, *l3pte; 1675 pt_entry_t *l1pte, *l2pte, *l3pte;
1676 pt_entry_t *saved_l2pte, *saved_l3pte; 1676 pt_entry_t *saved_l2pte, *saved_l3pte;
1677 vaddr_t l1eva, l2eva, l3vptva; 1677 vaddr_t l1eva, l2eva, l3vptva;
1678 pt_entry_t pte_bits; 1678 pt_entry_t pte_bits;
1679 1679
1680#ifdef DEBUG 1680#ifdef DEBUG
1681 if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT)) 1681 if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT))
1682 printf("pmap_remove(%p, %lx, %lx)\n", pmap, sva, eva); 1682 printf("pmap_remove(%p, %lx, %lx)\n", pmap, sva, eva);
1683#endif 1683#endif
1684 1684
1685 /* 1685 /*
1686 * If this is the kernel pmap, we can use a faster method 1686 * If this is the kernel pmap, we can use a faster method
1687 * for accessing the PTEs (since the PT pages are always 1687 * for accessing the PTEs (since the PT pages are always
1688 * resident). 1688 * resident).
1689 * 1689 *
1690 * Note that this routine should NEVER be called from an 1690 * Note that this routine should NEVER be called from an
1691 * interrupt context; pmap_kremove() is used for that. 1691 * interrupt context; pmap_kremove() is used for that.
1692 */ 1692 */
1693 if (pmap == pmap_kernel()) { 1693 if (pmap == pmap_kernel()) {
1694 PMAP_MAP_TO_HEAD_LOCK(); 1694 PMAP_MAP_TO_HEAD_LOCK();
1695 PMAP_LOCK(pmap); 1695 PMAP_LOCK(pmap);
1696 1696
1697 while (sva < eva) { 1697 while (sva < eva) {
1698 l3pte = PMAP_KERNEL_PTE(sva); 1698 l3pte = PMAP_KERNEL_PTE(sva);
1699 if (pmap_pte_v(l3pte)) { 1699 if (pmap_pte_v(l3pte)) {
1700 pte_bits = pmap_remove_mapping(pmap, sva, 1700 pte_bits = pmap_remove_mapping(pmap, sva,
1701 l3pte, true, NULL, tlbctx); 1701 l3pte, true, NULL, tlbctx);
1702 pmap_tlb_shootdown(pmap, sva, pte_bits, 1702 pmap_tlb_shootdown(pmap, sva, pte_bits,
1703 tlbctx); 1703 tlbctx);
1704 } 1704 }
1705 sva += PAGE_SIZE; 1705 sva += PAGE_SIZE;
1706 } 1706 }
1707 1707
1708 PMAP_MAP_TO_HEAD_UNLOCK(); 1708 PMAP_MAP_TO_HEAD_UNLOCK();
1709 PMAP_UNLOCK(pmap); 1709 PMAP_UNLOCK(pmap);
1710 pmap_tlb_shootnow(tlbctx); 1710 pmap_tlb_shootnow(tlbctx);
1711 pmap_tlb_ptpage_drain(tlbctx); 1711 pmap_tlb_ptpage_drain(tlbctx);
1712 TLB_COUNT(reason_remove_kernel); 1712 TLB_COUNT(reason_remove_kernel);
1713 1713
1714 return; 1714 return;
1715 } 1715 }
1716 1716
1717 KASSERT(sva < VM_MAXUSER_ADDRESS); 1717 KASSERT(sva < VM_MAXUSER_ADDRESS);
1718 KASSERT(eva <= VM_MAXUSER_ADDRESS); 1718 KASSERT(eva <= VM_MAXUSER_ADDRESS);
1719 KASSERT(pmap->pm_lev1map != kernel_lev1map); 1719 KASSERT(pmap->pm_lev1map != kernel_lev1map);
1720 1720
1721 PMAP_MAP_TO_HEAD_LOCK(); 1721 PMAP_MAP_TO_HEAD_LOCK();
1722 PMAP_LOCK(pmap); 1722 PMAP_LOCK(pmap);
1723 1723
1724 l1pte = pmap_l1pte(pmap, sva); 1724 l1pte = pmap_l1pte(pmap, sva);
1725 1725
1726 for (; sva < eva; sva = l1eva, l1pte++) { 1726 for (; sva < eva; sva = l1eva, l1pte++) {
1727 l1eva = alpha_trunc_l1seg(sva) + ALPHA_L1SEG_SIZE; 1727 l1eva = alpha_trunc_l1seg(sva) + ALPHA_L1SEG_SIZE;
1728 if (pmap_pte_v(l1pte)) { 1728 if (pmap_pte_v(l1pte)) {
1729 saved_l2pte = l2pte = pmap_l2pte(pmap, sva, l1pte); 1729 saved_l2pte = l2pte = pmap_l2pte(pmap, sva, l1pte);
1730 1730
1731 /* 1731 /*
1732 * Add a reference to the L2 table so it won't 1732 * Add a reference to the L2 table so it won't
1733 * get removed from under us. 1733 * get removed from under us.
1734 */ 1734 */
1735 pmap_physpage_addref(saved_l2pte); 1735 pmap_physpage_addref(saved_l2pte);
1736 1736
1737 for (; sva < l1eva && sva < eva; sva = l2eva, l2pte++) { 1737 for (; sva < l1eva && sva < eva; sva = l2eva, l2pte++) {
1738 l2eva = 1738 l2eva =
1739 alpha_trunc_l2seg(sva) + ALPHA_L2SEG_SIZE; 1739 alpha_trunc_l2seg(sva) + ALPHA_L2SEG_SIZE;
1740 if (pmap_pte_v(l2pte)) { 1740 if (pmap_pte_v(l2pte)) {
1741 saved_l3pte = l3pte = 1741 saved_l3pte = l3pte =
1742 pmap_l3pte(pmap, sva, l2pte); 1742 pmap_l3pte(pmap, sva, l2pte);
1743 1743
1744 /* 1744 /*
1745 * Add a reference to the L3 table so 1745 * Add a reference to the L3 table so
1746 * it won't get removed from under us. 1746 * it won't get removed from under us.
1747 */ 1747 */
1748 pmap_physpage_addref(saved_l3pte); 1748 pmap_physpage_addref(saved_l3pte);
1749 1749
1750 /* 1750 /*
1751 * Remember this sva; if the L3 table 1751 * Remember this sva; if the L3 table
1752 * gets removed, we need to invalidate 1752 * gets removed, we need to invalidate
1753 * the VPT TLB entry for it. 1753 * the VPT TLB entry for it.
1754 */ 1754 */
1755 l3vptva = sva; 1755 l3vptva = sva;
1756 1756
1757 for (; sva < l2eva && sva < eva; 1757 for (; sva < l2eva && sva < eva;
1758 sva += PAGE_SIZE, l3pte++) { 1758 sva += PAGE_SIZE, l3pte++) {
1759 if (!pmap_pte_v(l3pte)) { 1759 if (!pmap_pte_v(l3pte)) {
1760 continue; 1760 continue;
1761 } 1761 }
1762 pte_bits = 1762 pte_bits =
1763 pmap_remove_mapping( 1763 pmap_remove_mapping(
1764 pmap, sva, 1764 pmap, sva,
1765 l3pte, true, 1765 l3pte, true,
1766 NULL, tlbctx); 1766 NULL, tlbctx);
1767 pmap_tlb_shootdown(pmap, 1767 pmap_tlb_shootdown(pmap,
1768 sva, pte_bits, tlbctx); 1768 sva, pte_bits, tlbctx);
1769 } 1769 }
1770 1770
1771 /* 1771 /*
1772 * Remove the reference to the L3 1772 * Remove the reference to the L3
1773 * table that we added above. This 1773 * table that we added above. This
1774 * may free the L3 table. 1774 * may free the L3 table.
1775 */ 1775 */
1776 pmap_l3pt_delref(pmap, l3vptva, 1776 pmap_l3pt_delref(pmap, l3vptva,
1777 saved_l3pte, tlbctx); 1777 saved_l3pte, tlbctx);
1778 } 1778 }
1779 } 1779 }
1780 1780
1781 /* 1781 /*
1782 * Remove the reference to the L2 table that we 1782 * Remove the reference to the L2 table that we
1783 * added above. This may free the L2 table. 1783 * added above. This may free the L2 table.
1784 */ 1784 */
1785 pmap_l2pt_delref(pmap, l1pte, saved_l2pte, tlbctx); 1785 pmap_l2pt_delref(pmap, l1pte, saved_l2pte, tlbctx);
1786 } 1786 }
1787 } 1787 }
1788 1788
1789 PMAP_MAP_TO_HEAD_UNLOCK(); 1789 PMAP_MAP_TO_HEAD_UNLOCK();
1790 PMAP_UNLOCK(pmap); 1790 PMAP_UNLOCK(pmap);
1791 pmap_tlb_shootnow(tlbctx); 1791 pmap_tlb_shootnow(tlbctx);
1792 pmap_tlb_ptpage_drain(tlbctx); 1792 pmap_tlb_ptpage_drain(tlbctx);
1793 TLB_COUNT(reason_remove_user); 1793 TLB_COUNT(reason_remove_user);
1794} 1794}
1795 1795
1796void 1796void
1797pmap_remove(pmap_t pmap, vaddr_t sva, vaddr_t eva) 1797pmap_remove(pmap_t pmap, vaddr_t sva, vaddr_t eva)
1798{ 1798{
1799 struct pmap_tlb_context tlbctx; 1799 struct pmap_tlb_context tlbctx;
1800 1800
1801 pmap_tlb_context_init(&tlbctx, 0); 1801 pmap_tlb_context_init(&tlbctx, 0);
1802 pmap_remove_internal(pmap, sva, eva, &tlbctx); 1802 pmap_remove_internal(pmap, sva, eva, &tlbctx);
1803} 1803}
1804 1804
1805/* 1805/*
1806 * pmap_page_protect: [ INTERFACE ] 1806 * pmap_page_protect: [ INTERFACE ]
1807 * 1807 *
1808 * Lower the permission for all mappings to a given page to 1808 * Lower the permission for all mappings to a given page to
1809 * the permissions specified. 1809 * the permissions specified.
1810 */ 1810 */
1811void 1811void
1812pmap_page_protect(struct vm_page *pg, vm_prot_t prot) 1812pmap_page_protect(struct vm_page *pg, vm_prot_t prot)
1813{ 1813{
1814 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 1814 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
1815 pv_entry_t pv, nextpv; 1815 pv_entry_t pv, nextpv;
1816 pt_entry_t opte; 1816 pt_entry_t opte;
1817 kmutex_t *lock; 1817 kmutex_t *lock;
1818 struct pmap_tlb_context tlbctx; 1818 struct pmap_tlb_context tlbctx;
1819 1819
1820#ifdef DEBUG 1820#ifdef DEBUG
1821 paddr_t pa = VM_PAGE_TO_PHYS(pg); 1821 paddr_t pa = VM_PAGE_TO_PHYS(pg);
1822 1822
1823 1823
1824 if ((pmapdebug & (PDB_FOLLOW|PDB_PROTECT)) || 1824 if ((pmapdebug & (PDB_FOLLOW|PDB_PROTECT)) ||
1825 (prot == VM_PROT_NONE && (pmapdebug & PDB_REMOVE))) 1825 (prot == VM_PROT_NONE && (pmapdebug & PDB_REMOVE)))
1826 printf("pmap_page_protect(%p, %x)\n", pg, prot); 1826 printf("pmap_page_protect(%p, %x)\n", pg, prot);
1827#endif 1827#endif
1828 1828
1829 pmap_tlb_context_init(&tlbctx, TLB_CTX_F_PV); 1829 pmap_tlb_context_init(&tlbctx, TLB_CTX_F_PV);
1830 1830
1831 switch (prot) { 1831 switch (prot) {
1832 case VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE: 1832 case VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE:
1833 case VM_PROT_READ|VM_PROT_WRITE: 1833 case VM_PROT_READ|VM_PROT_WRITE:
1834 return; 1834 return;
1835 1835
1836 /* copy_on_write */ 1836 /* copy_on_write */
1837 case VM_PROT_READ|VM_PROT_EXECUTE: 1837 case VM_PROT_READ|VM_PROT_EXECUTE:
1838 case VM_PROT_READ: 1838 case VM_PROT_READ:
1839 PMAP_HEAD_TO_MAP_LOCK(); 1839 PMAP_HEAD_TO_MAP_LOCK();
1840 lock = pmap_pvh_lock(pg); 1840 lock = pmap_pvh_lock(pg);
1841 mutex_enter(lock); 1841 mutex_enter(lock);
1842 for (pv = md->pvh_list; pv != NULL; pv = pv->pv_next) { 1842 for (pv = md->pvh_list; pv != NULL; pv = pv->pv_next) {
1843 PMAP_LOCK(pv->pv_pmap); 1843 PMAP_LOCK(pv->pv_pmap);
1844 opte = atomic_load_relaxed(pv->pv_pte); 1844 opte = atomic_load_relaxed(pv->pv_pte);
1845 if (opte & (PG_KWE | PG_UWE)) { 1845 if (opte & (PG_KWE | PG_UWE)) {
1846 atomic_store_relaxed(pv->pv_pte, 1846 atomic_store_relaxed(pv->pv_pte,
1847 opte & ~(PG_KWE | PG_UWE)); 1847 opte & ~(PG_KWE | PG_UWE));
1848 pmap_tlb_shootdown_pv(pv->pv_pmap, pv->pv_va, 1848 pmap_tlb_shootdown_pv(pv->pv_pmap, pv->pv_va,
1849 opte, &tlbctx); 1849 opte, &tlbctx);
1850 } 1850 }
1851 PMAP_UNLOCK(pv->pv_pmap); 1851 PMAP_UNLOCK(pv->pv_pmap);
1852 } 1852 }
1853 mutex_exit(lock); 1853 mutex_exit(lock);
1854 PMAP_HEAD_TO_MAP_UNLOCK(); 1854 PMAP_HEAD_TO_MAP_UNLOCK();
1855 pmap_tlb_shootnow(&tlbctx); 1855 pmap_tlb_shootnow(&tlbctx);
1856 TLB_COUNT(reason_page_protect_read); 1856 TLB_COUNT(reason_page_protect_read);
1857 return; 1857 return;
1858 1858
1859 /* remove_all */ 1859 /* remove_all */
1860 default: 1860 default:
1861 break; 1861 break;
1862 } 1862 }
1863 1863
1864 PMAP_HEAD_TO_MAP_LOCK(); 1864 PMAP_HEAD_TO_MAP_LOCK();
1865 lock = pmap_pvh_lock(pg); 1865 lock = pmap_pvh_lock(pg);
1866 mutex_enter(lock); 1866 mutex_enter(lock);
1867 for (pv = md->pvh_list; pv != NULL; pv = nextpv) { 1867 for (pv = md->pvh_list; pv != NULL; pv = nextpv) {
1868 pt_entry_t pte_bits; 1868 pt_entry_t pte_bits;
1869 pmap_t pmap; 1869 pmap_t pmap;
1870 vaddr_t va; 1870 vaddr_t va;
1871 1871
1872 nextpv = pv->pv_next; 1872 nextpv = pv->pv_next;
1873 1873
1874 PMAP_LOCK(pv->pv_pmap); 1874 PMAP_LOCK(pv->pv_pmap);
1875 pmap = pv->pv_pmap; 1875 pmap = pv->pv_pmap;
1876 va = pv->pv_va; 1876 va = pv->pv_va;
1877 pte_bits = pmap_remove_mapping(pmap, va, pv->pv_pte, 1877 pte_bits = pmap_remove_mapping(pmap, va, pv->pv_pte,
1878 false, NULL, &tlbctx); 1878 false, NULL, &tlbctx);
1879 pmap_tlb_shootdown_pv(pmap, va, pte_bits, &tlbctx); 1879 pmap_tlb_shootdown_pv(pmap, va, pte_bits, &tlbctx);
1880 PMAP_UNLOCK(pv->pv_pmap); 1880 PMAP_UNLOCK(pv->pv_pmap);
1881 } 1881 }
1882 mutex_exit(lock); 1882 mutex_exit(lock);
1883 PMAP_HEAD_TO_MAP_UNLOCK(); 1883 PMAP_HEAD_TO_MAP_UNLOCK();
1884 pmap_tlb_shootnow(&tlbctx); 1884 pmap_tlb_shootnow(&tlbctx);
1885 pmap_tlb_ptpage_drain(&tlbctx); 1885 pmap_tlb_ptpage_drain(&tlbctx);
1886 TLB_COUNT(reason_page_protect_none); 1886 TLB_COUNT(reason_page_protect_none);
1887} 1887}
1888 1888
1889/* 1889/*
1890 * pmap_protect: [ INTERFACE ] 1890 * pmap_protect: [ INTERFACE ]
1891 * 1891 *
1892 * Set the physical protection on the specified range of this map 1892 * Set the physical protection on the specified range of this map
1893 * as requested. 1893 * as requested.
1894 */ 1894 */
1895void 1895void
1896pmap_protect(pmap_t pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot) 1896pmap_protect(pmap_t pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot)
1897{ 1897{
1898 pt_entry_t *l1pte, *l2pte, *l3pte, opte; 1898 pt_entry_t *l1pte, *l2pte, *l3pte, opte;
1899 vaddr_t l1eva, l2eva; 1899 vaddr_t l1eva, l2eva;
1900 struct pmap_tlb_context tlbctx; 1900 struct pmap_tlb_context tlbctx;
1901 1901
1902#ifdef DEBUG 1902#ifdef DEBUG
1903 if (pmapdebug & (PDB_FOLLOW|PDB_PROTECT)) 1903 if (pmapdebug & (PDB_FOLLOW|PDB_PROTECT))
1904 printf("pmap_protect(%p, %lx, %lx, %x)\n", 1904 printf("pmap_protect(%p, %lx, %lx, %x)\n",
1905 pmap, sva, eva, prot); 1905 pmap, sva, eva, prot);
1906#endif 1906#endif
1907 1907
1908 pmap_tlb_context_init(&tlbctx, 0); 1908 pmap_tlb_context_init(&tlbctx, 0);
1909 1909
1910 if ((prot & VM_PROT_READ) == VM_PROT_NONE) { 1910 if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
1911 pmap_remove_internal(pmap, sva, eva, &tlbctx); 1911 pmap_remove_internal(pmap, sva, eva, &tlbctx);
1912 return; 1912 return;
1913 } 1913 }
1914 1914
1915 const pt_entry_t bits = pte_prot(pmap, prot); 1915 const pt_entry_t bits = pte_prot(pmap, prot);
1916 1916
1917 PMAP_LOCK(pmap); 1917 PMAP_LOCK(pmap);
1918 1918
1919 l1pte = pmap_l1pte(pmap, sva); 1919 l1pte = pmap_l1pte(pmap, sva);
1920 for (; sva < eva; sva = l1eva, l1pte++) { 1920 for (; sva < eva; sva = l1eva, l1pte++) {
1921 l1eva = alpha_trunc_l1seg(sva) + ALPHA_L1SEG_SIZE; 1921 l1eva = alpha_trunc_l1seg(sva) + ALPHA_L1SEG_SIZE;
1922 if (pmap_pte_v(l1pte)) { 1922 if (pmap_pte_v(l1pte)) {
1923 l2pte = pmap_l2pte(pmap, sva, l1pte); 1923 l2pte = pmap_l2pte(pmap, sva, l1pte);
1924 for (; sva < l1eva && sva < eva; sva = l2eva, l2pte++) { 1924 for (; sva < l1eva && sva < eva; sva = l2eva, l2pte++) {
1925 l2eva = 1925 l2eva =
1926 alpha_trunc_l2seg(sva) + ALPHA_L2SEG_SIZE; 1926 alpha_trunc_l2seg(sva) + ALPHA_L2SEG_SIZE;
1927 if (pmap_pte_v(l2pte)) { 1927 if (pmap_pte_v(l2pte)) {
1928 l3pte = pmap_l3pte(pmap, sva, l2pte); 1928 l3pte = pmap_l3pte(pmap, sva, l2pte);
1929 for (; sva < l2eva && sva < eva; 1929 for (; sva < l2eva && sva < eva;
1930 sva += PAGE_SIZE, l3pte++) { 1930 sva += PAGE_SIZE, l3pte++) {
1931 if (pmap_pte_v(l3pte) && 1931 if (pmap_pte_v(l3pte) &&
1932 pmap_pte_prot_chg(l3pte, 1932 pmap_pte_prot_chg(l3pte,
1933 bits)) { 1933 bits)) {
1934 opte = atomic_load_relaxed(l3pte); 1934 opte = atomic_load_relaxed(l3pte);
1935 pmap_pte_set_prot(l3pte, 1935 pmap_pte_set_prot(l3pte,
1936 bits); 1936 bits);
1937 pmap_tlb_shootdown(pmap, 1937 pmap_tlb_shootdown(pmap,
1938 sva, opte, &tlbctx); 1938 sva, opte, &tlbctx);
1939 } 1939 }
1940 } 1940 }
1941 } 1941 }
1942 } 1942 }
1943 } 1943 }
1944 } 1944 }
1945 1945
1946 PMAP_UNLOCK(pmap); 1946 PMAP_UNLOCK(pmap);
1947 pmap_tlb_shootnow(&tlbctx); 1947 pmap_tlb_shootnow(&tlbctx);
1948 TLB_COUNT(reason_protect); 1948 TLB_COUNT(reason_protect);
1949} 1949}
1950 1950
1951/* 1951/*
1952 * pmap_enter_tlb_shootdown: 1952 * pmap_enter_tlb_shootdown:
1953 * 1953 *
1954 * Carry out a TLB shootdown on behalf of a pmap_enter() 1954 * Carry out a TLB shootdown on behalf of a pmap_enter()
1955 * or a pmap_kenter_pa(). This is factored out separately 1955 * or a pmap_kenter_pa(). This is factored out separately
1956 * because we expect it to be not a common case. 1956 * because we expect it to be not a common case.
1957 */ 1957 */
1958static void __noinline 1958static void __noinline
1959pmap_enter_tlb_shootdown(pmap_t const pmap, vaddr_t const va, 1959pmap_enter_tlb_shootdown(pmap_t const pmap, vaddr_t const va,
1960 pt_entry_t const pte_bits, bool locked) 1960 pt_entry_t const pte_bits, bool locked)
1961{ 1961{
1962 struct pmap_tlb_context tlbctx; 1962 struct pmap_tlb_context tlbctx;
1963 1963
1964 pmap_tlb_context_init(&tlbctx, 0); 1964 pmap_tlb_context_init(&tlbctx, 0);
1965 pmap_tlb_shootdown(pmap, va, pte_bits, &tlbctx); 1965 pmap_tlb_shootdown(pmap, va, pte_bits, &tlbctx);
1966 if (locked) { 1966 if (locked) {
1967 PMAP_UNLOCK(pmap); 1967 PMAP_UNLOCK(pmap);
1968 } 1968 }
1969 pmap_tlb_shootnow(&tlbctx); 1969 pmap_tlb_shootnow(&tlbctx);
1970} 1970}
1971 1971
1972/* 1972/*
1973 * pmap_enter_l2pt_delref: 1973 * pmap_enter_l2pt_delref:
1974 * 1974 *
1975 * Release a reference on an L2 PT page for pmap_enter(). 1975 * Release a reference on an L2 PT page for pmap_enter().
1976 * This is factored out separately becacause we expect it 1976 * This is factored out separately becacause we expect it
1977 * to be a rare case. 1977 * to be a rare case.
1978 */ 1978 */
1979static void __noinline 1979static void __noinline
1980pmap_enter_l2pt_delref(pmap_t const pmap, pt_entry_t * const l1pte, 1980pmap_enter_l2pt_delref(pmap_t const pmap, pt_entry_t * const l1pte,
1981 pt_entry_t * const l2pte) 1981 pt_entry_t * const l2pte)
1982{ 1982{
1983 struct pmap_tlb_context tlbctx; 1983 struct pmap_tlb_context tlbctx;
1984 1984
1985 /* 1985 /*
1986 * PALcode may have tried to service a TLB miss with 1986 * PALcode may have tried to service a TLB miss with
1987 * this L2 PTE, so we need to make sure we don't actully 1987 * this L2 PTE, so we need to make sure we don't actully
1988 * free the PT page untl we've shot down any TLB entries 1988 * free the PT page untl we've shot down any TLB entries
1989 * for this VPT index. 1989 * for this VPT index.
1990 */ 1990 */
1991 1991
1992 pmap_tlb_context_init(&tlbctx, 0); 1992 pmap_tlb_context_init(&tlbctx, 0);
1993 pmap_l2pt_delref(pmap, l1pte, l2pte, &tlbctx); 1993 pmap_l2pt_delref(pmap, l1pte, l2pte, &tlbctx);
1994 PMAP_UNLOCK(pmap); 1994 PMAP_UNLOCK(pmap);
1995 pmap_tlb_shootnow(&tlbctx); 1995 pmap_tlb_shootnow(&tlbctx);
1996 pmap_tlb_ptpage_drain(&tlbctx); 1996 pmap_tlb_ptpage_drain(&tlbctx);
1997 TLB_COUNT(reason_enter_l2pt_delref); 1997 TLB_COUNT(reason_enter_l2pt_delref);
1998} 1998}
1999 1999
2000/* 2000/*
2001 * pmap_enter_l3pt_delref: 2001 * pmap_enter_l3pt_delref:
2002 * 2002 *
2003 * Release a reference on an L3 PT page for pmap_enter(). 2003 * Release a reference on an L3 PT page for pmap_enter().
2004 * This is factored out separately becacause we expect it 2004 * This is factored out separately becacause we expect it
2005 * to be a rare case. 2005 * to be a rare case.
2006 */ 2006 */
2007static void __noinline 2007static void __noinline
2008pmap_enter_l3pt_delref(pmap_t const pmap, vaddr_t const va, 2008pmap_enter_l3pt_delref(pmap_t const pmap, vaddr_t const va,
2009 pt_entry_t * const pte) 2009 pt_entry_t * const pte)
2010{ 2010{
2011 struct pmap_tlb_context tlbctx; 2011 struct pmap_tlb_context tlbctx;
2012 2012
2013 /* 2013 /*
2014 * PALcode may have tried to service a TLB miss with 2014 * PALcode may have tried to service a TLB miss with
2015 * this PTE, so we need to make sure we don't actully 2015 * this PTE, so we need to make sure we don't actully
2016 * free the PT page untl we've shot down any TLB entries 2016 * free the PT page untl we've shot down any TLB entries
2017 * for this VPT index. 2017 * for this VPT index.
2018 */ 2018 */
2019 2019
2020 pmap_tlb_context_init(&tlbctx, 0); 2020 pmap_tlb_context_init(&tlbctx, 0);
2021 pmap_l3pt_delref(pmap, va, pte, &tlbctx); 2021 pmap_l3pt_delref(pmap, va, pte, &tlbctx);
2022 PMAP_UNLOCK(pmap); 2022 PMAP_UNLOCK(pmap);
2023 pmap_tlb_shootnow(&tlbctx); 2023 pmap_tlb_shootnow(&tlbctx);
2024 pmap_tlb_ptpage_drain(&tlbctx); 2024 pmap_tlb_ptpage_drain(&tlbctx);
2025 TLB_COUNT(reason_enter_l3pt_delref); 2025 TLB_COUNT(reason_enter_l3pt_delref);
2026} 2026}
2027 2027
2028/* 2028/*
2029 * pmap_enter: [ INTERFACE ] 2029 * pmap_enter: [ INTERFACE ]
2030 * 2030 *
2031 * Insert the given physical page (p) at 2031 * Insert the given physical page (p) at
2032 * the specified virtual address (v) in the 2032 * the specified virtual address (v) in the
2033 * target physical map with the protection requested. 2033 * target physical map with the protection requested.
2034 * 2034 *
2035 * If specified, the page will be wired down, meaning 2035 * If specified, the page will be wired down, meaning
2036 * that the related pte can not be reclaimed. 2036 * that the related pte can not be reclaimed.
2037 * 2037 *
2038 * Note: This is the only routine which MAY NOT lazy-evaluate 2038 * Note: This is the only routine which MAY NOT lazy-evaluate
2039 * or lose information. That is, this routine must actually 2039 * or lose information. That is, this routine must actually
2040 * insert this page into the given map NOW. 2040 * insert this page into the given map NOW.
2041 */ 2041 */
2042int 2042int
2043pmap_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags) 2043pmap_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags)
2044{ 2044{
2045 pt_entry_t *pte, npte, opte; 2045 pt_entry_t *pte, npte, opte;
2046 pv_entry_t opv = NULL; 2046 pv_entry_t opv = NULL;
2047 paddr_t opa; 2047 paddr_t opa;
2048 bool tflush = false; 2048 bool tflush = false;
2049 int error = 0; 2049 int error = 0;
2050 kmutex_t *lock; 2050 kmutex_t *lock;
2051 2051
2052#ifdef DEBUG 2052#ifdef DEBUG
2053 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER)) 2053 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER))
2054 printf("pmap_enter(%p, %lx, %lx, %x, %x)\n", 2054 printf("pmap_enter(%p, %lx, %lx, %x, %x)\n",
2055 pmap, va, pa, prot, flags); 2055 pmap, va, pa, prot, flags);
2056#endif 2056#endif
2057 struct vm_page * const pg = PHYS_TO_VM_PAGE(pa); 2057 struct vm_page * const pg = PHYS_TO_VM_PAGE(pa);
2058 const bool wired = (flags & PMAP_WIRED) != 0; 2058 const bool wired = (flags & PMAP_WIRED) != 0;
2059 2059
2060 PMAP_MAP_TO_HEAD_LOCK(); 2060 PMAP_MAP_TO_HEAD_LOCK();
2061 PMAP_LOCK(pmap); 2061 PMAP_LOCK(pmap);
2062 2062
2063 if (pmap == pmap_kernel()) { 2063 if (pmap == pmap_kernel()) {
2064 KASSERT(va >= VM_MIN_KERNEL_ADDRESS); 2064 KASSERT(va >= VM_MIN_KERNEL_ADDRESS);
2065 pte = PMAP_KERNEL_PTE(va); 2065 pte = PMAP_KERNEL_PTE(va);
2066 } else { 2066 } else {
2067 pt_entry_t *l1pte, *l2pte; 2067 pt_entry_t *l1pte, *l2pte;
2068 2068
2069 KASSERT(va < VM_MAXUSER_ADDRESS); 2069 KASSERT(va < VM_MAXUSER_ADDRESS);
2070 KASSERT(pmap->pm_lev1map != kernel_lev1map); 2070 KASSERT(pmap->pm_lev1map != kernel_lev1map);
2071 2071
2072 /* 2072 /*
2073 * Check to see if the level 1 PTE is valid, and 2073 * Check to see if the level 1 PTE is valid, and
2074 * allocate a new level 2 page table page if it's not. 2074 * allocate a new level 2 page table page if it's not.
2075 * A reference will be added to the level 2 table when 2075 * A reference will be added to the level 2 table when
2076 * the level 3 table is created. 2076 * the level 3 table is created.
2077 */ 2077 */
2078 l1pte = pmap_l1pte(pmap, va); 2078 l1pte = pmap_l1pte(pmap, va);
2079 if (pmap_pte_v(l1pte) == 0) { 2079 if (pmap_pte_v(l1pte) == 0) {
2080 pmap_physpage_addref(l1pte); 2080 pmap_physpage_addref(l1pte);
2081 error = pmap_ptpage_alloc(l1pte, PGU_L2PT); 2081 error = pmap_ptpage_alloc(l1pte, PGU_L2PT);
2082 if (error) { 2082 if (error) {
2083 pmap_l1pt_delref(pmap, l1pte); 2083 pmap_l1pt_delref(pmap, l1pte);
2084 if (flags & PMAP_CANFAIL) 2084 if (flags & PMAP_CANFAIL)
2085 goto out; 2085 goto out;
2086 panic("pmap_enter: unable to create L2 PT " 2086 panic("pmap_enter: unable to create L2 PT "
2087 "page"); 2087 "page");
2088 } 2088 }
2089#ifdef DEBUG 2089#ifdef DEBUG
2090 if (pmapdebug & PDB_PTPAGE) 2090 if (pmapdebug & PDB_PTPAGE)
2091 printf("pmap_enter: new level 2 table at " 2091 printf("pmap_enter: new level 2 table at "
2092 "0x%lx\n", pmap_pte_pa(l1pte)); 2092 "0x%lx\n", pmap_pte_pa(l1pte));
2093#endif 2093#endif
2094 } 2094 }
2095 2095
2096 /* 2096 /*
2097 * Check to see if the level 2 PTE is valid, and 2097 * Check to see if the level 2 PTE is valid, and
2098 * allocate a new level 3 page table page if it's not. 2098 * allocate a new level 3 page table page if it's not.
2099 * A reference will be added to the level 3 table when 2099 * A reference will be added to the level 3 table when
2100 * the mapping is validated. 2100 * the mapping is validated.
2101 */ 2101 */
2102 l2pte = pmap_l2pte(pmap, va, l1pte); 2102 l2pte = pmap_l2pte(pmap, va, l1pte);
2103 if (pmap_pte_v(l2pte) == 0) { 2103 if (pmap_pte_v(l2pte) == 0) {
2104 pmap_physpage_addref(l2pte); 2104 pmap_physpage_addref(l2pte);
2105 error = pmap_ptpage_alloc(l2pte, PGU_L3PT); 2105 error = pmap_ptpage_alloc(l2pte, PGU_L3PT);
2106 if (error) { 2106 if (error) {
2107 /* unlocks pmap */ 2107 /* unlocks pmap */
2108 pmap_enter_l2pt_delref(pmap, l1pte, l2pte); 2108 pmap_enter_l2pt_delref(pmap, l1pte, l2pte);
2109 if (flags & PMAP_CANFAIL) { 2109 if (flags & PMAP_CANFAIL) {
2110 PMAP_LOCK(pmap); 2110 PMAP_LOCK(pmap);
2111 goto out; 2111 goto out;
2112 } 2112 }
2113 panic("pmap_enter: unable to create L3 PT " 2113 panic("pmap_enter: unable to create L3 PT "
2114 "page"); 2114 "page");
2115 } 2115 }
2116#ifdef DEBUG 2116#ifdef DEBUG
2117 if (pmapdebug & PDB_PTPAGE) 2117 if (pmapdebug & PDB_PTPAGE)
2118 printf("pmap_enter: new level 3 table at " 2118 printf("pmap_enter: new level 3 table at "
2119 "0x%lx\n", pmap_pte_pa(l2pte)); 2119 "0x%lx\n", pmap_pte_pa(l2pte));
2120#endif 2120#endif
2121 } 2121 }
2122 2122
2123 /* 2123 /*
2124 * Get the PTE that will map the page. 2124 * Get the PTE that will map the page.
2125 */ 2125 */
2126 pte = pmap_l3pte(pmap, va, l2pte); 2126 pte = pmap_l3pte(pmap, va, l2pte);
2127 } 2127 }
2128 2128
2129 /* Remember all of the old PTE; used for TBI check later. */ 2129 /* Remember all of the old PTE; used for TBI check later. */
2130 opte = atomic_load_relaxed(pte); 2130 opte = atomic_load_relaxed(pte);
2131 2131
2132 /* 2132 /*
2133 * Check to see if the old mapping is valid. If not, validate the 2133 * Check to see if the old mapping is valid. If not, validate the
2134 * new one immediately. 2134 * new one immediately.
2135 */ 2135 */
2136 if ((opte & PG_V) == 0) { 2136 if ((opte & PG_V) == 0) {
2137 /* No TLB invalidatons needed for new mappings. */ 2137 /* No TLB invalidatons needed for new mappings. */
2138 2138
2139 if (pmap != pmap_kernel()) { 2139 if (pmap != pmap_kernel()) {
2140 /* 2140 /*
2141 * New mappings gain a reference on the level 3 2141 * New mappings gain a reference on the level 3
2142 * table. 2142 * table.
2143 */ 2143 */
2144 pmap_physpage_addref(pte); 2144 pmap_physpage_addref(pte);
2145 } 2145 }
2146 goto validate_enterpv; 2146 goto validate_enterpv;
2147 } 2147 }
2148 2148
2149 opa = pmap_pte_pa(pte); 2149 opa = pmap_pte_pa(pte);
2150 2150
2151 if (opa == pa) { 2151 if (opa == pa) {
2152 /* 2152 /*
2153 * Mapping has not changed; must be a protection or 2153 * Mapping has not changed; must be a protection or
2154 * wiring change. 2154 * wiring change.
2155 */ 2155 */
2156 if (pmap_pte_w_chg(pte, wired ? PG_WIRED : 0)) { 2156 if (pmap_pte_w_chg(pte, wired ? PG_WIRED : 0)) {
2157#ifdef DEBUG 2157#ifdef DEBUG
2158 if (pmapdebug & PDB_ENTER) 2158 if (pmapdebug & PDB_ENTER)
2159 printf("pmap_enter: wiring change -> %d\n", 2159 printf("pmap_enter: wiring change -> %d\n",
2160 wired); 2160 wired);
2161#endif 2161#endif
2162 /* Adjust the wiring count. */ 2162 /* Adjust the wiring count. */
2163 if (wired) 2163 if (wired)
2164 PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1); 2164 PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1);
2165 else 2165 else
2166 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1); 2166 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1);
2167 } 2167 }
2168 2168
2169 /* Set the PTE. */ 2169 /* Set the PTE. */
2170 goto validate; 2170 goto validate;
2171 } 2171 }
2172 2172
2173 /* 2173 /*
2174 * The mapping has changed. We need to invalidate the 2174 * The mapping has changed. We need to invalidate the
2175 * old mapping before creating the new one. 2175 * old mapping before creating the new one.
2176 */ 2176 */
2177#ifdef DEBUG 2177#ifdef DEBUG
2178 if (pmapdebug & PDB_ENTER) 2178 if (pmapdebug & PDB_ENTER)
2179 printf("pmap_enter: removing old mapping 0x%lx\n", va); 2179 printf("pmap_enter: removing old mapping 0x%lx\n", va);
2180#endif 2180#endif
2181 if (pmap != pmap_kernel()) { 2181 if (pmap != pmap_kernel()) {
2182 /* 2182 /*
2183 * Gain an extra reference on the level 3 table. 2183 * Gain an extra reference on the level 3 table.
2184 * pmap_remove_mapping() will delete a reference, 2184 * pmap_remove_mapping() will delete a reference,
2185 * and we don't want the table to be erroneously 2185 * and we don't want the table to be erroneously
2186 * freed. 2186 * freed.
2187 */ 2187 */
2188 pmap_physpage_addref(pte); 2188 pmap_physpage_addref(pte);
2189 } 2189 }
2190 /* Already have the bits from opte above. */ 2190 /* Already have the bits from opte above. */
2191 (void) pmap_remove_mapping(pmap, va, pte, true, &opv, NULL); 2191 (void) pmap_remove_mapping(pmap, va, pte, true, &opv, NULL);
2192 2192
2193 validate_enterpv: 2193 validate_enterpv:
2194 /* Enter the mapping into the pv_table if appropriate. */ 2194 /* Enter the mapping into the pv_table if appropriate. */
2195 if (pg != NULL) { 2195 if (pg != NULL) {
2196 error = pmap_pv_enter(pmap, pg, va, pte, true, opv); 2196 error = pmap_pv_enter(pmap, pg, va, pte, true, opv);
2197 if (error) { 2197 if (error) {
2198 /* This can only fail if opv == NULL */ 2198 /* This can only fail if opv == NULL */
2199 KASSERT(opv == NULL); 2199 KASSERT(opv == NULL);
2200 2200
2201 /* unlocks pmap */ 2201 /* unlocks pmap */
2202 pmap_enter_l3pt_delref(pmap, va, pte); 2202 pmap_enter_l3pt_delref(pmap, va, pte);
2203 if (flags & PMAP_CANFAIL) { 2203 if (flags & PMAP_CANFAIL) {
2204 PMAP_LOCK(pmap); 2204 PMAP_LOCK(pmap);
2205 goto out; 2205 goto out;
2206 } 2206 }
2207 panic("pmap_enter: unable to enter mapping in PV " 2207 panic("pmap_enter: unable to enter mapping in PV "
2208 "table"); 2208 "table");
2209 } 2209 }
2210 opv = NULL; 2210 opv = NULL;
2211 } 2211 }
2212 2212
2213 /* Increment counters. */ 2213 /* Increment counters. */
2214 PMAP_STAT_INCR(pmap->pm_stats.resident_count, 1); 2214 PMAP_STAT_INCR(pmap->pm_stats.resident_count, 1);
2215 if (wired) 2215 if (wired)
2216 PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1); 2216 PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1);
2217 2217
2218 validate: 2218 validate:
2219 /* Build the new PTE. */ 2219 /* Build the new PTE. */
2220 npte = ((pa >> PGSHIFT) << PG_SHIFT) | pte_prot(pmap, prot) | PG_V; 2220 npte = ((pa >> PGSHIFT) << PG_SHIFT) | pte_prot(pmap, prot) | PG_V;
2221 if (pg != NULL) { 2221 if (pg != NULL) {
2222 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 2222 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
2223 int attrs; 2223 int attrs;
2224 2224
2225 KASSERT(((flags & VM_PROT_ALL) & ~prot) == 0); 2225 KASSERT(((flags & VM_PROT_ALL) & ~prot) == 0);
2226 2226
2227 lock = pmap_pvh_lock(pg); 2227 lock = pmap_pvh_lock(pg);
2228 mutex_enter(lock); 2228 mutex_enter(lock);
2229 if (flags & VM_PROT_WRITE) 2229 if (flags & VM_PROT_WRITE)
2230 md->pvh_attrs |= (PGA_REFERENCED|PGA_MODIFIED); 2230 md->pvh_attrs |= (PGA_REFERENCED|PGA_MODIFIED);
2231 else if (flags & VM_PROT_ALL) 2231 else if (flags & VM_PROT_ALL)
2232 md->pvh_attrs |= PGA_REFERENCED; 2232 md->pvh_attrs |= PGA_REFERENCED;
2233 attrs = md->pvh_attrs; 2233 attrs = md->pvh_attrs;
2234 mutex_exit(lock); 2234 mutex_exit(lock);
2235 2235
2236 /* Set up referenced/modified emulation for new mapping. */ 2236 /* Set up referenced/modified emulation for new mapping. */
2237 if ((attrs & PGA_REFERENCED) == 0) 2237 if ((attrs & PGA_REFERENCED) == 0)
2238 npte |= PG_FOR | PG_FOW | PG_FOE; 2238 npte |= PG_FOR | PG_FOW | PG_FOE;
2239 else if ((attrs & PGA_MODIFIED) == 0) 2239 else if ((attrs & PGA_MODIFIED) == 0)
2240 npte |= PG_FOW; 2240 npte |= PG_FOW;
2241 2241
2242 /* 2242 /*
2243 * Mapping was entered on PV list. 2243 * Mapping was entered on PV list.
2244 */ 2244 */
2245 npte |= PG_PVLIST; 2245 npte |= PG_PVLIST;
2246 } 2246 }
2247 if (wired) 2247 if (wired)
2248 npte |= PG_WIRED; 2248 npte |= PG_WIRED;
2249#ifdef DEBUG 2249#ifdef DEBUG
2250 if (pmapdebug & PDB_ENTER) 2250 if (pmapdebug & PDB_ENTER)
2251 printf("pmap_enter: new pte = 0x%lx\n", npte); 2251 printf("pmap_enter: new pte = 0x%lx\n", npte);
2252#endif 2252#endif
2253 2253
2254 /* 2254 /*
2255 * If the HW / PALcode portion of the new PTE is the same as the 2255 * If the HW / PALcode portion of the new PTE is the same as the
2256 * old PTE, no TBI is necessary. 2256 * old PTE, no TBI is necessary.
2257 */ 2257 */
2258 if (opte & PG_V) { 2258 if (opte & PG_V) {
2259 tflush = PG_PALCODE(opte) != PG_PALCODE(npte); 2259 tflush = PG_PALCODE(opte) != PG_PALCODE(npte);
2260 } 2260 }
2261 2261
2262 /* Set the new PTE. */ 2262 /* Set the new PTE. */
2263 atomic_store_relaxed(pte, npte); 2263 atomic_store_relaxed(pte, npte);
2264 2264
2265out: 2265out:
2266 PMAP_MAP_TO_HEAD_UNLOCK(); 2266 PMAP_MAP_TO_HEAD_UNLOCK();
2267 2267
2268 /* 2268 /*
2269 * Invalidate the TLB entry for this VA and any appropriate 2269 * Invalidate the TLB entry for this VA and any appropriate
2270 * caches. 2270 * caches.
2271 */ 2271 */
2272 if (tflush) { 2272 if (tflush) {
2273 /* unlocks pmap */ 2273 /* unlocks pmap */
2274 pmap_enter_tlb_shootdown(pmap, va, opte, true); 2274 pmap_enter_tlb_shootdown(pmap, va, opte, true);
2275 if (pmap == pmap_kernel()) { 2275 if (pmap == pmap_kernel()) {
2276 TLB_COUNT(reason_enter_kernel); 2276 TLB_COUNT(reason_enter_kernel);
2277 } else { 2277 } else {
2278 TLB_COUNT(reason_enter_user); 2278 TLB_COUNT(reason_enter_user);
2279 } 2279 }
2280 } else { 2280 } else {
2281 PMAP_UNLOCK(pmap); 2281 PMAP_UNLOCK(pmap);
2282 } 2282 }
2283 2283
2284 if (opv) 2284 if (opv)
2285 pmap_pv_free(opv); 2285 pmap_pv_free(opv);
2286 2286
2287 return error; 2287 return error;
2288} 2288}
2289 2289
2290/* 2290/*
2291 * pmap_kenter_pa: [ INTERFACE ] 2291 * pmap_kenter_pa: [ INTERFACE ]
2292 * 2292 *
2293 * Enter a va -> pa mapping into the kernel pmap without any 2293 * Enter a va -> pa mapping into the kernel pmap without any
2294 * physical->virtual tracking. 2294 * physical->virtual tracking.
2295 * 2295 *
2296 * Note: no locking is necessary in this function. 2296 * Note: no locking is necessary in this function.
2297 */ 2297 */
2298void 2298void
2299pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags) 2299pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags)
2300{ 2300{
2301 pmap_t const pmap = pmap_kernel(); 2301 pmap_t const pmap = pmap_kernel();
2302 2302
2303#ifdef DEBUG 2303#ifdef DEBUG
2304 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER)) 2304 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER))
2305 printf("pmap_kenter_pa(%lx, %lx, %x)\n", 2305 printf("pmap_kenter_pa(%lx, %lx, %x)\n",
2306 va, pa, prot); 2306 va, pa, prot);
2307#endif 2307#endif
2308 2308
2309 KASSERT(va >= VM_MIN_KERNEL_ADDRESS); 2309 KASSERT(va >= VM_MIN_KERNEL_ADDRESS);
2310 2310
2311 pt_entry_t * const pte = PMAP_KERNEL_PTE(va); 2311 pt_entry_t * const pte = PMAP_KERNEL_PTE(va);
2312 2312
2313 /* Build the new PTE. */ 2313 /* Build the new PTE. */
2314 const pt_entry_t npte = 2314 const pt_entry_t npte =
2315 ((pa >> PGSHIFT) << PG_SHIFT) | pte_prot(pmap_kernel(), prot) | 2315 ((pa >> PGSHIFT) << PG_SHIFT) | pte_prot(pmap_kernel(), prot) |
2316 PG_V | PG_WIRED; 2316 PG_V | PG_WIRED;
2317 2317
2318 /* Set the new PTE. */ 2318 /* Set the new PTE. */
2319 const pt_entry_t opte = atomic_load_relaxed(pte); 2319 const pt_entry_t opte = atomic_load_relaxed(pte);
2320 atomic_store_relaxed(pte, npte); 2320 atomic_store_relaxed(pte, npte);
2321 2321
2322 PMAP_STAT_INCR(pmap->pm_stats.resident_count, 1); 2322 PMAP_STAT_INCR(pmap->pm_stats.resident_count, 1);
2323 PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1); 2323 PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1);
2324 2324
2325 /* 2325 /*
2326 * There should not have been anything here, previously, 2326 * There should not have been anything here, previously,
2327 * so we can skip TLB shootdowns, etc. in the common case. 2327 * so we can skip TLB shootdowns, etc. in the common case.
2328 */ 2328 */
2329 if (__predict_false(opte & PG_V)) { 2329 if (__predict_false(opte & PG_V)) {
2330 const pt_entry_t diff = npte ^ opte; 2330 const pt_entry_t diff = npte ^ opte;
2331 2331
2332 printf_nolog("%s: mapping already present\n", __func__); 2332 printf_nolog("%s: mapping already present\n", __func__);
2333 PMAP_STAT_DECR(pmap->pm_stats.resident_count, 1); 2333 PMAP_STAT_DECR(pmap->pm_stats.resident_count, 1);
2334 if (diff & PG_WIRED) 2334 if (diff & PG_WIRED)
2335 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1); 2335 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1);
2336 /* XXX Can't handle this case. */ 2336 /* XXX Can't handle this case. */
2337 if (diff & PG_PVLIST) 2337 if (diff & PG_PVLIST)
2338 panic("pmap_kenter_pa: old mapping was managed"); 2338 panic("pmap_kenter_pa: old mapping was managed");
2339 2339
2340 pmap_enter_tlb_shootdown(pmap_kernel(), va, opte, false); 2340 pmap_enter_tlb_shootdown(pmap_kernel(), va, opte, false);
2341 TLB_COUNT(reason_kenter); 2341 TLB_COUNT(reason_kenter);
2342 } 2342 }
2343} 2343}
2344 2344
2345/* 2345/*
2346 * pmap_kremove: [ INTERFACE ] 2346 * pmap_kremove: [ INTERFACE ]
2347 * 2347 *
2348 * Remove a mapping entered with pmap_kenter_pa() starting at va, 2348 * Remove a mapping entered with pmap_kenter_pa() starting at va,
2349 * for size bytes (assumed to be page rounded). 2349 * for size bytes (assumed to be page rounded).
2350 */ 2350 */
2351void 2351void
2352pmap_kremove(vaddr_t va, vsize_t size) 2352pmap_kremove(vaddr_t va, vsize_t size)
2353{ 2353{
2354 pt_entry_t *pte, opte; 2354 pt_entry_t *pte, opte;
2355 pmap_t const pmap = pmap_kernel(); 2355 pmap_t const pmap = pmap_kernel();
2356 struct pmap_tlb_context tlbctx; 2356 struct pmap_tlb_context tlbctx;
2357 int count = 0; 2357 int count = 0;
2358 2358
2359#ifdef DEBUG 2359#ifdef DEBUG
2360 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER)) 2360 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER))
2361 printf("pmap_kremove(%lx, %lx)\n", 2361 printf("pmap_kremove(%lx, %lx)\n",
2362 va, size); 2362 va, size);
2363#endif 2363#endif
2364 2364
2365 pmap_tlb_context_init(&tlbctx, 0); 2365 pmap_tlb_context_init(&tlbctx, 0);
2366 2366
2367 KASSERT(va >= VM_MIN_KERNEL_ADDRESS); 2367 KASSERT(va >= VM_MIN_KERNEL_ADDRESS);
2368 2368
2369 for (; size != 0; size -= PAGE_SIZE, va += PAGE_SIZE) { 2369 for (; size != 0; size -= PAGE_SIZE, va += PAGE_SIZE) {
2370 pte = PMAP_KERNEL_PTE(va); 2370 pte = PMAP_KERNEL_PTE(va);
2371 opte = atomic_load_relaxed(pte); 2371 opte = atomic_load_relaxed(pte);
2372 if (opte & PG_V) { 2372 if (opte & PG_V) {
2373 KASSERT((opte & PG_PVLIST) == 0); 2373 KASSERT((opte & PG_PVLIST) == 0);
2374 2374
2375 /* Zap the mapping. */ 2375 /* Zap the mapping. */
2376 atomic_store_relaxed(pte, PG_NV); 2376 atomic_store_relaxed(pte, PG_NV);
2377 pmap_tlb_shootdown(pmap, va, opte, &tlbctx); 2377 pmap_tlb_shootdown(pmap, va, opte, &tlbctx);
2378 2378
2379 count++; 2379 count++;
2380 } 2380 }
2381 } 2381 }
2382 2382
2383 /* Update stats. */ 2383 /* Update stats. */
2384 if (__predict_true(count != 0)) { 2384 if (__predict_true(count != 0)) {
2385 PMAP_STAT_DECR(pmap->pm_stats.resident_count, count); 2385 PMAP_STAT_DECR(pmap->pm_stats.resident_count, count);
2386 PMAP_STAT_DECR(pmap->pm_stats.wired_count, count); 2386 PMAP_STAT_DECR(pmap->pm_stats.wired_count, count);
2387 } 2387 }
2388 2388
2389 pmap_tlb_shootnow(&tlbctx); 2389 pmap_tlb_shootnow(&tlbctx);
2390 TLB_COUNT(reason_kremove); 2390 TLB_COUNT(reason_kremove);
2391} 2391}
2392 2392
2393/* 2393/*
2394 * pmap_unwire: [ INTERFACE ] 2394 * pmap_unwire: [ INTERFACE ]
2395 * 2395 *
2396 * Clear the wired attribute for a map/virtual-address pair. 2396 * Clear the wired attribute for a map/virtual-address pair.
2397 * 2397 *
2398 * The mapping must already exist in the pmap. 2398 * The mapping must already exist in the pmap.
2399 */ 2399 */
2400void 2400void
2401pmap_unwire(pmap_t pmap, vaddr_t va) 2401pmap_unwire(pmap_t pmap, vaddr_t va)
2402{ 2402{
2403 pt_entry_t *pte; 2403 pt_entry_t *pte;
2404 2404
2405#ifdef DEBUG 2405#ifdef DEBUG
2406 if (pmapdebug & PDB_FOLLOW) 2406 if (pmapdebug & PDB_FOLLOW)
2407 printf("pmap_unwire(%p, %lx)\n", pmap, va); 2407 printf("pmap_unwire(%p, %lx)\n", pmap, va);
2408#endif 2408#endif
2409 2409
2410 PMAP_LOCK(pmap); 2410 PMAP_LOCK(pmap);
2411 2411
2412 pte = pmap_l3pte(pmap, va, NULL); 2412 pte = pmap_l3pte(pmap, va, NULL);
2413 2413
2414 KASSERT(pte != NULL); 2414 KASSERT(pte != NULL);
2415 KASSERT(pmap_pte_v(pte)); 2415 KASSERT(pmap_pte_v(pte));
2416 2416
2417 /* 2417 /*
2418 * If wiring actually changed (always?) clear the wire bit and 2418 * If wiring actually changed (always?) clear the wire bit and
2419 * update the wire count. Note that wiring is not a hardware 2419 * update the wire count. Note that wiring is not a hardware
2420 * characteristic so there is no need to invalidate the TLB. 2420 * characteristic so there is no need to invalidate the TLB.
2421 */ 2421 */
2422 if (pmap_pte_w_chg(pte, 0)) { 2422 if (pmap_pte_w_chg(pte, 0)) {
2423 pmap_pte_set_w(pte, false); 2423 pmap_pte_set_w(pte, false);
2424 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1); 2424 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1);
2425 } 2425 }
2426#ifdef DEBUG 2426#ifdef DEBUG
2427 else { 2427 else {
2428 printf("pmap_unwire: wiring for pmap %p va 0x%lx " 2428 printf("pmap_unwire: wiring for pmap %p va 0x%lx "
2429 "didn't change!\n", pmap, va); 2429 "didn't change!\n", pmap, va);
2430 } 2430 }
2431#endif 2431#endif
2432 2432
2433 PMAP_UNLOCK(pmap); 2433 PMAP_UNLOCK(pmap);
2434} 2434}
2435 2435
2436/* 2436/*
2437 * pmap_extract: [ INTERFACE ] 2437 * pmap_extract: [ INTERFACE ]
2438 * 2438 *
2439 * Extract the physical address associated with the given 2439 * Extract the physical address associated with the given
2440 * pmap/virtual address pair. 2440 * pmap/virtual address pair.
2441 */ 2441 */
2442bool 2442bool
2443pmap_extract(pmap_t pmap, vaddr_t va, paddr_t *pap) 2443pmap_extract(pmap_t pmap, vaddr_t va, paddr_t *pap)
2444{ 2444{
2445 pt_entry_t *l1pte, *l2pte, *l3pte; 2445 pt_entry_t *l1pte, *l2pte, *l3pte;
2446 paddr_t pa; 2446 paddr_t pa;
2447 2447
2448#ifdef DEBUG 2448#ifdef DEBUG
2449 if (pmapdebug & PDB_FOLLOW) 2449 if (pmapdebug & PDB_FOLLOW)
2450 printf("pmap_extract(%p, %lx) -> ", pmap, va); 2450 printf("pmap_extract(%p, %lx) -> ", pmap, va);
2451#endif 2451#endif
2452 2452
2453 /* 2453 /*
2454 * Take a faster path for the kernel pmap. Avoids locking, 2454 * Take a faster path for the kernel pmap. Avoids locking,
2455 * handles K0SEG. 2455 * handles K0SEG.
2456 */ 2456 */
2457 if (__predict_true(pmap == pmap_kernel())) { 2457 if (__predict_true(pmap == pmap_kernel())) {
2458 if (__predict_true(vtophys_internal(va, pap))) { 2458 if (__predict_true(vtophys_internal(va, pap))) {
2459#ifdef DEBUG 2459#ifdef DEBUG
2460 if (pmapdebug & PDB_FOLLOW) 2460 if (pmapdebug & PDB_FOLLOW)
2461 printf("0x%lx (kernel vtophys)\n", pa); 2461 printf("0x%lx (kernel vtophys)\n", pa);
2462#endif 2462#endif
2463 return true; 2463 return true;
2464 } 2464 }
2465#ifdef DEBUG 2465#ifdef DEBUG
2466 if (pmapdebug & PDB_FOLLOW) 2466 if (pmapdebug & PDB_FOLLOW)
2467 printf("failed (kernel vtophys)\n"); 2467 printf("failed (kernel vtophys)\n");
2468#endif 2468#endif
2469 return false; 2469 return false;
2470 } 2470 }
2471 2471
2472 PMAP_LOCK(pmap); 2472 PMAP_LOCK(pmap);
2473 2473
2474 l1pte = pmap_l1pte(pmap, va); 2474 l1pte = pmap_l1pte(pmap, va);
2475 if (pmap_pte_v(l1pte) == 0) 2475 if (pmap_pte_v(l1pte) == 0)
2476 goto out; 2476 goto out;
2477 2477
2478 l2pte = pmap_l2pte(pmap, va, l1pte); 2478 l2pte = pmap_l2pte(pmap, va, l1pte);
2479 if (pmap_pte_v(l2pte) == 0) 2479 if (pmap_pte_v(l2pte) == 0)
2480 goto out; 2480 goto out;
2481 2481
2482 l3pte = pmap_l3pte(pmap, va, l2pte); 2482 l3pte = pmap_l3pte(pmap, va, l2pte);
2483 if (pmap_pte_v(l3pte) == 0) 2483 if (pmap_pte_v(l3pte) == 0)
2484 goto out; 2484 goto out;
2485 2485
2486 pa = pmap_pte_pa(l3pte) | (va & PGOFSET); 2486 pa = pmap_pte_pa(l3pte) | (va & PGOFSET);
2487 PMAP_UNLOCK(pmap); 2487 PMAP_UNLOCK(pmap);
2488 if (pap != NULL) 2488 if (pap != NULL)
2489 *pap = pa; 2489 *pap = pa;
2490#ifdef DEBUG 2490#ifdef DEBUG
2491 if (pmapdebug & PDB_FOLLOW) 2491 if (pmapdebug & PDB_FOLLOW)
2492 printf("0x%lx\n", pa); 2492 printf("0x%lx\n", pa);
2493#endif 2493#endif
2494 return (true); 2494 return (true);
2495 2495
2496 out: 2496 out:
2497 PMAP_UNLOCK(pmap); 2497 PMAP_UNLOCK(pmap);
2498#ifdef DEBUG 2498#ifdef DEBUG
2499 if (pmapdebug & PDB_FOLLOW) 2499 if (pmapdebug & PDB_FOLLOW)
2500 printf("failed\n"); 2500 printf("failed\n");
2501#endif 2501#endif
2502 return (false); 2502 return (false);
2503} 2503}
2504 2504
2505/* 2505/*
2506 * pmap_copy: [ INTERFACE ] 2506 * pmap_copy: [ INTERFACE ]
2507 * 2507 *
2508 * Copy the mapping range specified by src_addr/len 2508 * Copy the mapping range specified by src_addr/len
2509 * from the source map to the range dst_addr/len 2509 * from the source map to the range dst_addr/len
2510 * in the destination map. 2510 * in the destination map.
2511 * 2511 *
2512 * This routine is only advisory and need not do anything. 2512 * This routine is only advisory and need not do anything.
2513 */ 2513 */
2514/* call deleted in <machine/pmap.h> */ 2514/* call deleted in <machine/pmap.h> */
2515 2515
2516/* 2516/*
2517 * pmap_update: [ INTERFACE ] 2517 * pmap_update: [ INTERFACE ]
2518 * 2518 *
2519 * Require that all active physical maps contain no 2519 * Require that all active physical maps contain no
2520 * incorrect entries NOW, by processing any deferred 2520 * incorrect entries NOW, by processing any deferred
2521 * pmap operations. 2521 * pmap operations.
2522 */ 2522 */
2523/* call deleted in <machine/pmap.h> */ 2523/* call deleted in <machine/pmap.h> */
2524 2524
2525/* 2525/*
2526 * pmap_activate: [ INTERFACE ] 2526 * pmap_activate: [ INTERFACE ]
2527 * 2527 *
2528 * Activate the pmap used by the specified process. This includes 2528 * Activate the pmap used by the specified process. This includes
2529 * reloading the MMU context of the current process, and marking 2529 * reloading the MMU context of the current process, and marking
2530 * the pmap in use by the processor. 2530 * the pmap in use by the processor.
2531 */ 2531 */
2532void 2532void
2533pmap_activate(struct lwp *l) 2533pmap_activate(struct lwp *l)
2534{ 2534{
2535 struct pmap * const pmap = l->l_proc->p_vmspace->vm_map.pmap; 2535 struct pmap * const pmap = l->l_proc->p_vmspace->vm_map.pmap;
2536 struct pcb * const pcb = lwp_getpcb(l); 2536 struct pcb * const pcb = lwp_getpcb(l);
2537 2537
2538#ifdef DEBUG 2538#ifdef DEBUG
2539 if (pmapdebug & PDB_FOLLOW) 2539 if (pmapdebug & PDB_FOLLOW)
2540 printf("pmap_activate(%p)\n", l); 2540 printf("pmap_activate(%p)\n", l);
2541#endif 2541#endif
2542 2542
2543 KASSERT(kpreempt_disabled()); 2543 KASSERT(kpreempt_disabled());
2544 2544
2545 struct cpu_info * const ci = curcpu(); 2545 struct cpu_info * const ci = curcpu();
2546 2546
2547 KASSERT(l == ci->ci_curlwp); 2547 KASSERT(l == ci->ci_curlwp);
2548 2548
2549 u_long const old_ptbr = pcb->pcb_hw.apcb_ptbr; 2549 u_long const old_ptbr = pcb->pcb_hw.apcb_ptbr;
2550 u_int const old_asn = pcb->pcb_hw.apcb_asn; 2550 u_int const old_asn = pcb->pcb_hw.apcb_asn;
2551 2551
2552 /* 2552 /*
2553 * We hold the activation lock to synchronize with TLB shootdown. 2553 * We hold the activation lock to synchronize with TLB shootdown.
2554 * The kernel pmap does not require those tests because shootdowns 2554 * The kernel pmap does not require those tests because shootdowns
2555 * for the kernel pmap are always sent to all CPUs. 2555 * for the kernel pmap are always sent to all CPUs.
2556 */ 2556 */
2557 if (pmap != pmap_kernel()) { 2557 if (pmap != pmap_kernel()) {
2558 PMAP_ACT_LOCK(pmap); 2558 PMAP_ACT_LOCK(pmap);
2559 pcb->pcb_hw.apcb_asn = pmap_asn_alloc(pmap, ci); 2559 pcb->pcb_hw.apcb_asn = pmap_asn_alloc(pmap, ci);
2560 atomic_or_ulong(&pmap->pm_cpus, (1UL << ci->ci_cpuid)); 2560 atomic_or_ulong(&pmap->pm_cpus, (1UL << ci->ci_cpuid));
2561 } else { 2561 } else {
2562 pcb->pcb_hw.apcb_asn = PMAP_ASN_KERNEL; 2562 pcb->pcb_hw.apcb_asn = PMAP_ASN_KERNEL;
2563 } 2563 }
2564 pcb->pcb_hw.apcb_ptbr = 2564 pcb->pcb_hw.apcb_ptbr =
2565 ALPHA_K0SEG_TO_PHYS((vaddr_t)pmap->pm_lev1map) >> PGSHIFT; 2565 ALPHA_K0SEG_TO_PHYS((vaddr_t)pmap->pm_lev1map) >> PGSHIFT;
2566 2566
2567 /* 2567 /*
2568 * Check to see if the ASN or page table base has changed; if 2568 * Check to see if the ASN or page table base has changed; if
2569 * so, switch to our own context again so that it will take 2569 * so, switch to our own context again so that it will take
2570 * effect. 2570 * effect.
2571 * 2571 *
2572 * We test ASN first because it's the most likely value to change. 2572 * We test ASN first because it's the most likely value to change.
2573 */ 2573 */
2574 if (old_asn != pcb->pcb_hw.apcb_asn || 2574 if (old_asn != pcb->pcb_hw.apcb_asn ||
2575 old_ptbr != pcb->pcb_hw.apcb_ptbr) { 2575 old_ptbr != pcb->pcb_hw.apcb_ptbr) {
2576 if (old_asn != pcb->pcb_hw.apcb_asn && 2576 if (old_asn != pcb->pcb_hw.apcb_asn &&
2577 old_ptbr != pcb->pcb_hw.apcb_ptbr) { 2577 old_ptbr != pcb->pcb_hw.apcb_ptbr) {
2578 TLB_COUNT(activate_both_change); 2578 TLB_COUNT(activate_both_change);
2579 } else if (old_asn != pcb->pcb_hw.apcb_asn) { 2579 } else if (old_asn != pcb->pcb_hw.apcb_asn) {
2580 TLB_COUNT(activate_asn_change); 2580 TLB_COUNT(activate_asn_change);
2581 } else { 2581 } else {
2582 TLB_COUNT(activate_ptbr_change); 2582 TLB_COUNT(activate_ptbr_change);
2583 } 2583 }
@@ -2818,1076 +2818,1076 @@ pmap_clear_reference(struct vm_page *pg) @@ -2818,1076 +2818,1076 @@ pmap_clear_reference(struct vm_page *pg)
2818 return (rv); 2818 return (rv);
2819} 2819}
2820 2820
2821/* 2821/*
2822 * pmap_is_referenced: [ INTERFACE ] 2822 * pmap_is_referenced: [ INTERFACE ]
2823 * 2823 *
2824 * Return whether or not the specified physical page is referenced 2824 * Return whether or not the specified physical page is referenced
2825 * by any physical maps. 2825 * by any physical maps.
2826 */ 2826 */
2827/* See <machine/pmap.h> */ 2827/* See <machine/pmap.h> */
2828 2828
2829/* 2829/*
2830 * pmap_is_modified: [ INTERFACE ] 2830 * pmap_is_modified: [ INTERFACE ]
2831 * 2831 *
2832 * Return whether or not the specified physical page is modified 2832 * Return whether or not the specified physical page is modified
2833 * by any physical maps. 2833 * by any physical maps.
2834 */ 2834 */
2835/* See <machine/pmap.h> */ 2835/* See <machine/pmap.h> */
2836 2836
2837/* 2837/*
2838 * pmap_phys_address: [ INTERFACE ] 2838 * pmap_phys_address: [ INTERFACE ]
2839 * 2839 *
2840 * Return the physical address corresponding to the specified 2840 * Return the physical address corresponding to the specified
2841 * cookie. Used by the device pager to decode a device driver's 2841 * cookie. Used by the device pager to decode a device driver's
2842 * mmap entry point return value. 2842 * mmap entry point return value.
2843 * 2843 *
2844 * Note: no locking is necessary in this function. 2844 * Note: no locking is necessary in this function.
2845 */ 2845 */
2846paddr_t 2846paddr_t
2847pmap_phys_address(paddr_t ppn) 2847pmap_phys_address(paddr_t ppn)
2848{ 2848{
2849 2849
2850 return (alpha_ptob(ppn)); 2850 return (alpha_ptob(ppn));
2851} 2851}
2852 2852
2853/* 2853/*
2854 * Miscellaneous support routines follow 2854 * Miscellaneous support routines follow
2855 */ 2855 */
2856 2856
2857/* 2857/*
2858 * alpha_protection_init: 2858 * alpha_protection_init:
2859 * 2859 *
2860 * Initialize Alpha protection code array. 2860 * Initialize Alpha protection code array.
2861 * 2861 *
2862 * Note: no locking is necessary in this function. 2862 * Note: no locking is necessary in this function.
2863 */ 2863 */
2864static void 2864static void
2865alpha_protection_init(void) 2865alpha_protection_init(void)
2866{ 2866{
2867 int prot, *kp, *up; 2867 int prot, *kp, *up;
2868 2868
2869 kp = protection_codes[0]; 2869 kp = protection_codes[0];
2870 up = protection_codes[1]; 2870 up = protection_codes[1];
2871 2871
2872 for (prot = 0; prot < 8; prot++) { 2872 for (prot = 0; prot < 8; prot++) {
2873 kp[prot] = PG_ASM; 2873 kp[prot] = PG_ASM;
2874 up[prot] = 0; 2874 up[prot] = 0;
2875 2875
2876 if (prot & VM_PROT_READ) { 2876 if (prot & VM_PROT_READ) {
2877 kp[prot] |= PG_KRE; 2877 kp[prot] |= PG_KRE;
2878 up[prot] |= PG_KRE | PG_URE; 2878 up[prot] |= PG_KRE | PG_URE;
2879 } 2879 }
2880 if (prot & VM_PROT_WRITE) { 2880 if (prot & VM_PROT_WRITE) {
2881 kp[prot] |= PG_KWE; 2881 kp[prot] |= PG_KWE;
2882 up[prot] |= PG_KWE | PG_UWE; 2882 up[prot] |= PG_KWE | PG_UWE;
2883 } 2883 }
2884 if (prot & VM_PROT_EXECUTE) { 2884 if (prot & VM_PROT_EXECUTE) {
2885 kp[prot] |= PG_EXEC | PG_KRE; 2885 kp[prot] |= PG_EXEC | PG_KRE;
2886 up[prot] |= PG_EXEC | PG_KRE | PG_URE; 2886 up[prot] |= PG_EXEC | PG_KRE | PG_URE;
2887 } else { 2887 } else {
2888 kp[prot] |= PG_FOE; 2888 kp[prot] |= PG_FOE;
2889 up[prot] |= PG_FOE; 2889 up[prot] |= PG_FOE;
2890 } 2890 }
2891 } 2891 }
2892} 2892}
2893 2893
2894/* 2894/*
2895 * pmap_remove_mapping: 2895 * pmap_remove_mapping:
2896 * 2896 *
2897 * Invalidate a single page denoted by pmap/va. 2897 * Invalidate a single page denoted by pmap/va.
2898 * 2898 *
2899 * If (pte != NULL), it is the already computed PTE for the page. 2899 * If (pte != NULL), it is the already computed PTE for the page.
2900 * 2900 *
2901 * Note: locking in this function is complicated by the fact 2901 * Note: locking in this function is complicated by the fact
2902 * that we can be called when the PV list is already locked. 2902 * that we can be called when the PV list is already locked.
2903 * (pmap_page_protect()). In this case, the caller must be 2903 * (pmap_page_protect()). In this case, the caller must be
2904 * careful to get the next PV entry while we remove this entry 2904 * careful to get the next PV entry while we remove this entry
2905 * from beneath it. We assume that the pmap itself is already 2905 * from beneath it. We assume that the pmap itself is already
2906 * locked; dolock applies only to the PV list. 2906 * locked; dolock applies only to the PV list.
2907 * 2907 *
2908 * Returns important PTE bits that the caller needs to check for 2908 * Returns important PTE bits that the caller needs to check for
2909 * TLB / I-stream invalidation purposes. 2909 * TLB / I-stream invalidation purposes.
2910 */ 2910 */
2911static pt_entry_t 2911static pt_entry_t
2912pmap_remove_mapping(pmap_t pmap, vaddr_t va, pt_entry_t *pte, 2912pmap_remove_mapping(pmap_t pmap, vaddr_t va, pt_entry_t *pte,
2913 bool dolock, pv_entry_t *opvp, struct pmap_tlb_context * const tlbctx) 2913 bool dolock, pv_entry_t *opvp, struct pmap_tlb_context * const tlbctx)
2914{ 2914{
2915 pt_entry_t opte; 2915 pt_entry_t opte;
2916 paddr_t pa; 2916 paddr_t pa;
2917 struct vm_page *pg; /* if != NULL, page is managed */ 2917 struct vm_page *pg; /* if != NULL, page is managed */
2918 2918
2919#ifdef DEBUG 2919#ifdef DEBUG
2920 if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT)) 2920 if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT))
2921 printf("pmap_remove_mapping(%p, %lx, %p, %d, %p)\n", 2921 printf("pmap_remove_mapping(%p, %lx, %p, %d, %p)\n",
2922 pmap, va, pte, dolock, opvp); 2922 pmap, va, pte, dolock, opvp);
2923#endif 2923#endif
2924 2924
2925 /* 2925 /*
2926 * PTE not provided, compute it from pmap and va. 2926 * PTE not provided, compute it from pmap and va.
2927 */ 2927 */
2928 if (pte == NULL) { 2928 if (pte == NULL) {
2929 pte = pmap_l3pte(pmap, va, NULL); 2929 pte = pmap_l3pte(pmap, va, NULL);
2930 if (pmap_pte_v(pte) == 0) 2930 if (pmap_pte_v(pte) == 0)
2931 return 0; 2931 return 0;
2932 } 2932 }
2933 2933
2934 opte = *pte; 2934 opte = *pte;
2935 2935
2936 pa = PG_PFNUM(opte) << PGSHIFT; 2936 pa = PG_PFNUM(opte) << PGSHIFT;
2937 2937
2938 /* 2938 /*
2939 * Update statistics 2939 * Update statistics
2940 */ 2940 */
2941 if (pmap_pte_w(pte)) 2941 if (pmap_pte_w(pte))
2942 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1); 2942 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1);
2943 PMAP_STAT_DECR(pmap->pm_stats.resident_count, 1); 2943 PMAP_STAT_DECR(pmap->pm_stats.resident_count, 1);
2944 2944
2945 /* 2945 /*
2946 * Invalidate the PTE after saving the reference modify info. 2946 * Invalidate the PTE after saving the reference modify info.
2947 */ 2947 */
2948#ifdef DEBUG 2948#ifdef DEBUG
2949 if (pmapdebug & PDB_REMOVE) 2949 if (pmapdebug & PDB_REMOVE)
2950 printf("remove: invalidating pte at %p\n", pte); 2950 printf("remove: invalidating pte at %p\n", pte);
2951#endif 2951#endif
2952 atomic_store_relaxed(pte, PG_NV); 2952 atomic_store_relaxed(pte, PG_NV);
2953 2953
2954 /* 2954 /*
2955 * If we're removing a user mapping, check to see if we 2955 * If we're removing a user mapping, check to see if we
2956 * can free page table pages. 2956 * can free page table pages.
2957 */ 2957 */
2958 if (pmap != pmap_kernel()) { 2958 if (pmap != pmap_kernel()) {
2959 /* 2959 /*
2960 * Delete the reference on the level 3 table. It will 2960 * Delete the reference on the level 3 table. It will
2961 * delete references on the level 2 and 1 tables as 2961 * delete references on the level 2 and 1 tables as
2962 * appropriate. 2962 * appropriate.
2963 */ 2963 */
2964 pmap_l3pt_delref(pmap, va, pte, tlbctx); 2964 pmap_l3pt_delref(pmap, va, pte, tlbctx);
2965 } 2965 }
2966 2966
2967 if (opte & PG_PVLIST) { 2967 if (opte & PG_PVLIST) {
2968 /* 2968 /*
2969 * Remove it from the PV table. 2969 * Remove it from the PV table.
2970 */ 2970 */
2971 pg = PHYS_TO_VM_PAGE(pa); 2971 pg = PHYS_TO_VM_PAGE(pa);
2972 KASSERT(pg != NULL); 2972 KASSERT(pg != NULL);
2973 pmap_pv_remove(pmap, pg, va, dolock, opvp); 2973 pmap_pv_remove(pmap, pg, va, dolock, opvp);
2974 KASSERT(opvp == NULL || *opvp != NULL); 2974 KASSERT(opvp == NULL || *opvp != NULL);
2975 } 2975 }
2976 2976
2977 return opte & (PG_V | PG_ASM | PG_EXEC); 2977 return opte & (PG_V | PG_ASM | PG_EXEC);
2978} 2978}
2979 2979
2980/* 2980/*
2981 * pmap_changebit: 2981 * pmap_changebit:
2982 * 2982 *
2983 * Set or clear the specified PTE bits for all mappings on the 2983 * Set or clear the specified PTE bits for all mappings on the
2984 * specified page. 2984 * specified page.
2985 * 2985 *
2986 * Note: we assume that the pv_head is already locked, and that 2986 * Note: we assume that the pv_head is already locked, and that
2987 * the caller has acquired a PV->pmap mutex so that we can lock 2987 * the caller has acquired a PV->pmap mutex so that we can lock
2988 * the pmaps as we encounter them. 2988 * the pmaps as we encounter them.
2989 */ 2989 */
2990static void 2990static void
2991pmap_changebit(struct vm_page *pg, pt_entry_t set, pt_entry_t mask, 2991pmap_changebit(struct vm_page *pg, pt_entry_t set, pt_entry_t mask,
2992 struct pmap_tlb_context * const tlbctx) 2992 struct pmap_tlb_context * const tlbctx)
2993{ 2993{
2994 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 2994 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
2995 pv_entry_t pv; 2995 pv_entry_t pv;
2996 pt_entry_t *pte, npte, opte; 2996 pt_entry_t *pte, npte, opte;
2997 2997
2998#ifdef DEBUG 2998#ifdef DEBUG
2999 if (pmapdebug & PDB_BITS) 2999 if (pmapdebug & PDB_BITS)
3000 printf("pmap_changebit(%p, 0x%lx, 0x%lx)\n", 3000 printf("pmap_changebit(%p, 0x%lx, 0x%lx)\n",
3001 pg, set, mask); 3001 pg, set, mask);
3002#endif 3002#endif
3003 3003
3004 /* 3004 /*
3005 * Loop over all current mappings setting/clearing as apropos. 3005 * Loop over all current mappings setting/clearing as apropos.
3006 */ 3006 */
3007 for (pv = md->pvh_list; pv != NULL; pv = pv->pv_next) { 3007 for (pv = md->pvh_list; pv != NULL; pv = pv->pv_next) {
3008 PMAP_LOCK(pv->pv_pmap); 3008 PMAP_LOCK(pv->pv_pmap);
3009 3009
3010 pte = pv->pv_pte; 3010 pte = pv->pv_pte;
3011 3011
3012 opte = atomic_load_relaxed(pte); 3012 opte = atomic_load_relaxed(pte);
3013 npte = (opte | set) & mask; 3013 npte = (opte | set) & mask;
3014 if (npte != opte) { 3014 if (npte != opte) {
3015 atomic_store_relaxed(pte, npte); 3015 atomic_store_relaxed(pte, npte);
3016 pmap_tlb_shootdown_pv(pv->pv_pmap, pv->pv_va, 3016 pmap_tlb_shootdown_pv(pv->pv_pmap, pv->pv_va,
3017 opte, tlbctx); 3017 opte, tlbctx);
3018 } 3018 }
3019 PMAP_UNLOCK(pv->pv_pmap); 3019 PMAP_UNLOCK(pv->pv_pmap);
3020 } 3020 }
3021} 3021}
3022 3022
3023/* 3023/*
3024 * pmap_emulate_reference: 3024 * pmap_emulate_reference:
3025 * 3025 *
3026 * Emulate reference and/or modified bit hits. 3026 * Emulate reference and/or modified bit hits.
3027 * Return 1 if this was an execute fault on a non-exec mapping, 3027 * Return 1 if this was an execute fault on a non-exec mapping,
3028 * otherwise return 0. 3028 * otherwise return 0.
3029 */ 3029 */
3030int 3030int
3031pmap_emulate_reference(struct lwp *l, vaddr_t v, int user, int type) 3031pmap_emulate_reference(struct lwp *l, vaddr_t v, int user, int type)
3032{ 3032{
3033 struct pmap *pmap = l->l_proc->p_vmspace->vm_map.pmap; 3033 struct pmap *pmap = l->l_proc->p_vmspace->vm_map.pmap;
3034 pt_entry_t faultoff, *pte; 3034 pt_entry_t faultoff, *pte;
3035 struct vm_page *pg; 3035 struct vm_page *pg;
3036 paddr_t pa; 3036 paddr_t pa;
3037 bool didlock = false; 3037 bool didlock = false;
3038 bool exec = false; 3038 bool exec = false;
3039 kmutex_t *lock; 3039 kmutex_t *lock;
3040 3040
3041#ifdef DEBUG 3041#ifdef DEBUG
3042 if (pmapdebug & PDB_FOLLOW) 3042 if (pmapdebug & PDB_FOLLOW)
3043 printf("pmap_emulate_reference: %p, 0x%lx, %d, %d\n", 3043 printf("pmap_emulate_reference: %p, 0x%lx, %d, %d\n",
3044 l, v, user, type); 3044 l, v, user, type);
3045#endif 3045#endif
3046 3046
3047 /* 3047 /*
3048 * Convert process and virtual address to physical address. 3048 * Convert process and virtual address to physical address.
3049 */ 3049 */
3050 if (v >= VM_MIN_KERNEL_ADDRESS) { 3050 if (v >= VM_MIN_KERNEL_ADDRESS) {
3051 if (user) 3051 if (user)
3052 panic("pmap_emulate_reference: user ref to kernel"); 3052 panic("pmap_emulate_reference: user ref to kernel");
3053 /* 3053 /*
3054 * No need to lock here; kernel PT pages never go away. 3054 * No need to lock here; kernel PT pages never go away.
3055 */ 3055 */
3056 pte = PMAP_KERNEL_PTE(v); 3056 pte = PMAP_KERNEL_PTE(v);
3057 } else { 3057 } else {
3058#ifdef DIAGNOSTIC 3058#ifdef DIAGNOSTIC
3059 if (l == NULL) 3059 if (l == NULL)
3060 panic("pmap_emulate_reference: bad proc"); 3060 panic("pmap_emulate_reference: bad proc");
3061 if (l->l_proc->p_vmspace == NULL) 3061 if (l->l_proc->p_vmspace == NULL)
3062 panic("pmap_emulate_reference: bad p_vmspace"); 3062 panic("pmap_emulate_reference: bad p_vmspace");
3063#endif 3063#endif
3064 PMAP_LOCK(pmap); 3064 PMAP_LOCK(pmap);
3065 didlock = true; 3065 didlock = true;
3066 pte = pmap_l3pte(pmap, v, NULL); 3066 pte = pmap_l3pte(pmap, v, NULL);
3067 /* 3067 /*
3068 * We'll unlock below where we're done with the PTE. 3068 * We'll unlock below where we're done with the PTE.
3069 */ 3069 */
3070 } 3070 }
3071 exec = pmap_pte_exec(pte); 3071 exec = pmap_pte_exec(pte);
3072 if (!exec && type == ALPHA_MMCSR_FOE) { 3072 if (!exec && type == ALPHA_MMCSR_FOE) {
3073 if (didlock) 3073 if (didlock)
3074 PMAP_UNLOCK(pmap); 3074 PMAP_UNLOCK(pmap);
3075 return (1); 3075 return (1);
3076 } 3076 }
3077#ifdef DEBUG 3077#ifdef DEBUG
3078 if (pmapdebug & PDB_FOLLOW) { 3078 if (pmapdebug & PDB_FOLLOW) {
3079 printf("\tpte = %p, ", pte); 3079 printf("\tpte = %p, ", pte);
3080 printf("*pte = 0x%lx\n", *pte); 3080 printf("*pte = 0x%lx\n", *pte);
3081 } 3081 }
3082#endif 3082#endif
3083 3083
3084 pa = pmap_pte_pa(pte); 3084 pa = pmap_pte_pa(pte);
3085 3085
3086 /* 3086 /*
3087 * We're now done with the PTE. If it was a user pmap, unlock 3087 * We're now done with the PTE. If it was a user pmap, unlock
3088 * it now. 3088 * it now.
3089 */ 3089 */
3090 if (didlock) 3090 if (didlock)
3091 PMAP_UNLOCK(pmap); 3091 PMAP_UNLOCK(pmap);
3092 3092
3093#ifdef DEBUG 3093#ifdef DEBUG
3094 if (pmapdebug & PDB_FOLLOW) 3094 if (pmapdebug & PDB_FOLLOW)
3095 printf("\tpa = 0x%lx\n", pa); 3095 printf("\tpa = 0x%lx\n", pa);
3096#endif 3096#endif
3097#ifdef DIAGNOSTIC 3097#ifdef DIAGNOSTIC
3098 if (!uvm_pageismanaged(pa)) 3098 if (!uvm_pageismanaged(pa))
3099 panic("pmap_emulate_reference(%p, 0x%lx, %d, %d): " 3099 panic("pmap_emulate_reference(%p, 0x%lx, %d, %d): "
3100 "pa 0x%lx not managed", l, v, user, type, pa); 3100 "pa 0x%lx not managed", l, v, user, type, pa);
3101#endif 3101#endif
3102 3102
3103 /* 3103 /*
3104 * Twiddle the appropriate bits to reflect the reference 3104 * Twiddle the appropriate bits to reflect the reference
3105 * and/or modification.. 3105 * and/or modification..
3106 * 3106 *
3107 * The rules: 3107 * The rules:
3108 * (1) always mark page as used, and 3108 * (1) always mark page as used, and
3109 * (2) if it was a write fault, mark page as modified. 3109 * (2) if it was a write fault, mark page as modified.
3110 */ 3110 */
3111 pg = PHYS_TO_VM_PAGE(pa); 3111 pg = PHYS_TO_VM_PAGE(pa);
3112 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 3112 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
3113 struct pmap_tlb_context tlbctx; 3113 struct pmap_tlb_context tlbctx;
3114 3114
3115 pmap_tlb_context_init(&tlbctx, TLB_CTX_F_PV); 3115 pmap_tlb_context_init(&tlbctx, TLB_CTX_F_PV);
3116 3116
3117 PMAP_HEAD_TO_MAP_LOCK(); 3117 PMAP_HEAD_TO_MAP_LOCK();
3118 lock = pmap_pvh_lock(pg); 3118 lock = pmap_pvh_lock(pg);
3119 mutex_enter(lock); 3119 mutex_enter(lock);
3120 3120
3121 if (type == ALPHA_MMCSR_FOW) { 3121 if (type == ALPHA_MMCSR_FOW) {
3122 md->pvh_attrs |= (PGA_REFERENCED|PGA_MODIFIED); 3122 md->pvh_attrs |= (PGA_REFERENCED|PGA_MODIFIED);
3123 faultoff = PG_FOR | PG_FOW; 3123 faultoff = PG_FOR | PG_FOW;
3124 } else { 3124 } else {
3125 md->pvh_attrs |= PGA_REFERENCED; 3125 md->pvh_attrs |= PGA_REFERENCED;
3126 faultoff = PG_FOR; 3126 faultoff = PG_FOR;
3127 if (exec) { 3127 if (exec) {
3128 faultoff |= PG_FOE; 3128 faultoff |= PG_FOE;
3129 } 3129 }
3130 } 3130 }
3131 pmap_changebit(pg, 0, ~faultoff, &tlbctx); 3131 pmap_changebit(pg, 0, ~faultoff, &tlbctx);
3132 3132
3133 mutex_exit(lock); 3133 mutex_exit(lock);
3134 PMAP_HEAD_TO_MAP_UNLOCK(); 3134 PMAP_HEAD_TO_MAP_UNLOCK();
3135 3135
3136 pmap_tlb_shootnow(&tlbctx); 3136 pmap_tlb_shootnow(&tlbctx);
3137 TLB_COUNT(reason_emulate_reference); 3137 TLB_COUNT(reason_emulate_reference);
3138 3138
3139 return (0); 3139 return (0);
3140} 3140}
3141 3141
3142#ifdef DEBUG 3142#ifdef DEBUG
3143/* 3143/*
3144 * pmap_pv_dump: 3144 * pmap_pv_dump:
3145 * 3145 *
3146 * Dump the physical->virtual data for the specified page. 3146 * Dump the physical->virtual data for the specified page.
3147 */ 3147 */
3148void 3148void
3149pmap_pv_dump(paddr_t pa) 3149pmap_pv_dump(paddr_t pa)
3150{ 3150{
3151 struct vm_page *pg; 3151 struct vm_page *pg;
3152 struct vm_page_md *md; 3152 struct vm_page_md *md;
3153 pv_entry_t pv; 3153 pv_entry_t pv;
3154 kmutex_t *lock; 3154 kmutex_t *lock;
3155 3155
3156 pg = PHYS_TO_VM_PAGE(pa); 3156 pg = PHYS_TO_VM_PAGE(pa);
3157 md = VM_PAGE_TO_MD(pg); 3157 md = VM_PAGE_TO_MD(pg);
3158 3158
3159 lock = pmap_pvh_lock(pg); 3159 lock = pmap_pvh_lock(pg);
3160 mutex_enter(lock); 3160 mutex_enter(lock);
3161 3161
3162 printf("pa 0x%lx (attrs = 0x%x):\n", pa, md->pvh_attrs); 3162 printf("pa 0x%lx (attrs = 0x%x):\n", pa, md->pvh_attrs);
3163 for (pv = md->pvh_list; pv != NULL; pv = pv->pv_next) 3163 for (pv = md->pvh_list; pv != NULL; pv = pv->pv_next)
3164 printf(" pmap %p, va 0x%lx\n", 3164 printf(" pmap %p, va 0x%lx\n",
3165 pv->pv_pmap, pv->pv_va); 3165 pv->pv_pmap, pv->pv_va);
3166 printf("\n"); 3166 printf("\n");
3167 3167
3168 mutex_exit(lock); 3168 mutex_exit(lock);
3169} 3169}
3170#endif 3170#endif
3171 3171
3172/* 3172/*
3173 * vtophys: 3173 * vtophys:
3174 * 3174 *
3175 * Return the physical address corresponding to the K0SEG or 3175 * Return the physical address corresponding to the K0SEG or
3176 * K1SEG address provided. 3176 * K1SEG address provided.
3177 * 3177 *
3178 * Note: no locking is necessary in this function. 3178 * Note: no locking is necessary in this function.
3179 */ 3179 */
3180static bool 3180static bool
3181vtophys_internal(vaddr_t const vaddr, paddr_t * const pap) 3181vtophys_internal(vaddr_t const vaddr, paddr_t * const pap)
3182{ 3182{
3183 paddr_t pa; 3183 paddr_t pa;
3184 3184
3185 KASSERT(vaddr >= ALPHA_K0SEG_BASE); 3185 KASSERT(vaddr >= ALPHA_K0SEG_BASE);
3186 3186
3187 if (vaddr <= ALPHA_K0SEG_END) { 3187 if (vaddr <= ALPHA_K0SEG_END) {
3188 pa = ALPHA_K0SEG_TO_PHYS(vaddr); 3188 pa = ALPHA_K0SEG_TO_PHYS(vaddr);
3189 } else { 3189 } else {
3190 pt_entry_t * const pte = PMAP_KERNEL_PTE(vaddr); 3190 pt_entry_t * const pte = PMAP_KERNEL_PTE(vaddr);
3191 if (__predict_false(! pmap_pte_v(pte))) { 3191 if (__predict_false(! pmap_pte_v(pte))) {
3192 return false; 3192 return false;
3193 } 3193 }
3194 pa = pmap_pte_pa(pte) | (vaddr & PGOFSET); 3194 pa = pmap_pte_pa(pte) | (vaddr & PGOFSET);
3195 } 3195 }
3196 3196
3197 if (pap != NULL) { 3197 if (pap != NULL) {
3198 *pap = pa; 3198 *pap = pa;
3199 } 3199 }
3200 3200
3201 return true; 3201 return true;
3202} 3202}
3203 3203
3204paddr_t 3204paddr_t
3205vtophys(vaddr_t const vaddr) 3205vtophys(vaddr_t const vaddr)
3206{ 3206{
3207 paddr_t pa; 3207 paddr_t pa;
3208 3208
3209 if (__predict_false(! vtophys_internal(vaddr, &pa))) 3209 if (__predict_false(! vtophys_internal(vaddr, &pa)))
3210 pa = 0; 3210 pa = 0;
3211 return pa; 3211 return pa;
3212} 3212}
3213 3213
3214/******************** pv_entry management ********************/ 3214/******************** pv_entry management ********************/
3215 3215
3216/* 3216/*
3217 * pmap_pv_enter: 3217 * pmap_pv_enter:
3218 * 3218 *
3219 * Add a physical->virtual entry to the pv_table. 3219 * Add a physical->virtual entry to the pv_table.
3220 */ 3220 */
3221static int 3221static int
3222pmap_pv_enter(pmap_t pmap, struct vm_page *pg, vaddr_t va, pt_entry_t *pte, 3222pmap_pv_enter(pmap_t pmap, struct vm_page *pg, vaddr_t va, pt_entry_t *pte,
3223 bool dolock, pv_entry_t newpv) 3223 bool dolock, pv_entry_t newpv)
3224{ 3224{
3225 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 3225 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
3226 kmutex_t *lock; 3226 kmutex_t *lock;
3227 3227
3228 /* 3228 /*
3229 * Allocate and fill in the new pv_entry. 3229 * Allocate and fill in the new pv_entry.
3230 */ 3230 */
3231 if (newpv == NULL) { 3231 if (newpv == NULL) {
3232 newpv = pmap_pv_alloc(); 3232 newpv = pmap_pv_alloc();
3233 if (newpv == NULL) 3233 if (newpv == NULL)
3234 return ENOMEM; 3234 return ENOMEM;
3235 } 3235 }
3236 newpv->pv_va = va; 3236 newpv->pv_va = va;
3237 newpv->pv_pmap = pmap; 3237 newpv->pv_pmap = pmap;
3238 newpv->pv_pte = pte; 3238 newpv->pv_pte = pte;
3239 3239
3240 if (dolock) { 3240 if (dolock) {
3241 lock = pmap_pvh_lock(pg); 3241 lock = pmap_pvh_lock(pg);
3242 mutex_enter(lock); 3242 mutex_enter(lock);
3243 } 3243 }
3244 3244
3245#ifdef DEBUG 3245#ifdef DEBUG
3246 { 3246 {
3247 pv_entry_t pv; 3247 pv_entry_t pv;
3248 /* 3248 /*
3249 * Make sure the entry doesn't already exist. 3249 * Make sure the entry doesn't already exist.
3250 */ 3250 */
3251 for (pv = md->pvh_list; pv != NULL; pv = pv->pv_next) { 3251 for (pv = md->pvh_list; pv != NULL; pv = pv->pv_next) {
3252 if (pmap == pv->pv_pmap && va == pv->pv_va) { 3252 if (pmap == pv->pv_pmap && va == pv->pv_va) {
3253 printf("pmap = %p, va = 0x%lx\n", pmap, va); 3253 printf("pmap = %p, va = 0x%lx\n", pmap, va);
3254 panic("pmap_pv_enter: already in pv table"); 3254 panic("pmap_pv_enter: already in pv table");
3255 } 3255 }
3256 } 3256 }
3257 } 3257 }
3258#endif 3258#endif
3259 3259
3260 /* 3260 /*
3261 * ...and put it in the list. 3261 * ...and put it in the list.
3262 */ 3262 */
3263 newpv->pv_next = md->pvh_list; 3263 newpv->pv_next = md->pvh_list;
3264 md->pvh_list = newpv; 3264 md->pvh_list = newpv;
3265 3265
3266 if (dolock) { 3266 if (dolock) {
3267 mutex_exit(lock); 3267 mutex_exit(lock);
3268 } 3268 }
3269 3269
3270 return 0; 3270 return 0;
3271} 3271}
3272 3272
3273/* 3273/*
3274 * pmap_pv_remove: 3274 * pmap_pv_remove:
3275 * 3275 *
3276 * Remove a physical->virtual entry from the pv_table. 3276 * Remove a physical->virtual entry from the pv_table.
3277 */ 3277 */
3278static void 3278static void
3279pmap_pv_remove(pmap_t pmap, struct vm_page *pg, vaddr_t va, bool dolock, 3279pmap_pv_remove(pmap_t pmap, struct vm_page *pg, vaddr_t va, bool dolock,
3280 pv_entry_t *opvp) 3280 pv_entry_t *opvp)
3281{ 3281{
3282 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 3282 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
3283 pv_entry_t pv, *pvp; 3283 pv_entry_t pv, *pvp;
3284 kmutex_t *lock; 3284 kmutex_t *lock;
3285 3285
3286 if (dolock) { 3286 if (dolock) {
3287 lock = pmap_pvh_lock(pg); 3287 lock = pmap_pvh_lock(pg);
3288 mutex_enter(lock); 3288 mutex_enter(lock);
3289 } else { 3289 } else {
3290 lock = NULL; /* XXX stupid gcc */ 3290 lock = NULL; /* XXX stupid gcc */
3291 } 3291 }
3292 3292
3293 /* 3293 /*
3294 * Find the entry to remove. 3294 * Find the entry to remove.
3295 */ 3295 */
3296 for (pvp = &md->pvh_list, pv = *pvp; 3296 for (pvp = &md->pvh_list, pv = *pvp;
3297 pv != NULL; pvp = &pv->pv_next, pv = *pvp) 3297 pv != NULL; pvp = &pv->pv_next, pv = *pvp)
3298 if (pmap == pv->pv_pmap && va == pv->pv_va) 3298 if (pmap == pv->pv_pmap && va == pv->pv_va)
3299 break; 3299 break;
3300 3300
3301 KASSERT(pv != NULL); 3301 KASSERT(pv != NULL);
3302 3302
3303 *pvp = pv->pv_next; 3303 *pvp = pv->pv_next;
3304 3304
3305 if (dolock) { 3305 if (dolock) {
3306 mutex_exit(lock); 3306 mutex_exit(lock);
3307 } 3307 }
3308 3308
3309 if (opvp != NULL) 3309 if (opvp != NULL)
3310 *opvp = pv; 3310 *opvp = pv;
3311 else 3311 else
3312 pmap_pv_free(pv); 3312 pmap_pv_free(pv);
3313} 3313}
3314 3314
3315/* 3315/*
3316 * pmap_pv_page_alloc: 3316 * pmap_pv_page_alloc:
3317 * 3317 *
3318 * Allocate a page for the pv_entry pool. 3318 * Allocate a page for the pv_entry pool.
3319 */ 3319 */
3320static void * 3320static void *
3321pmap_pv_page_alloc(struct pool *pp, int flags) 3321pmap_pv_page_alloc(struct pool *pp, int flags)
3322{ 3322{
3323 paddr_t pg; 3323 paddr_t pg;
3324 3324
3325 if (pmap_physpage_alloc(PGU_PVENT, &pg)) 3325 if (pmap_physpage_alloc(PGU_PVENT, &pg))
3326 return ((void *)ALPHA_PHYS_TO_K0SEG(pg)); 3326 return ((void *)ALPHA_PHYS_TO_K0SEG(pg));
3327 return (NULL); 3327 return (NULL);
3328} 3328}
3329 3329
3330/* 3330/*
3331 * pmap_pv_page_free: 3331 * pmap_pv_page_free:
3332 * 3332 *
3333 * Free a pv_entry pool page. 3333 * Free a pv_entry pool page.
3334 */ 3334 */
3335static void 3335static void
3336pmap_pv_page_free(struct pool *pp, void *v) 3336pmap_pv_page_free(struct pool *pp, void *v)
3337{ 3337{
3338 3338
3339 pmap_physpage_free(ALPHA_K0SEG_TO_PHYS((vaddr_t)v)); 3339 pmap_physpage_free(ALPHA_K0SEG_TO_PHYS((vaddr_t)v));
3340} 3340}
3341 3341
3342/******************** misc. functions ********************/ 3342/******************** misc. functions ********************/
3343 3343
3344/* 3344/*
3345 * pmap_physpage_alloc: 3345 * pmap_physpage_alloc:
3346 * 3346 *
3347 * Allocate a single page from the VM system and return the 3347 * Allocate a single page from the VM system and return the
3348 * physical address for that page. 3348 * physical address for that page.
3349 */ 3349 */
3350static bool 3350static bool
3351pmap_physpage_alloc(int usage, paddr_t *pap) 3351pmap_physpage_alloc(int usage, paddr_t *pap)
3352{ 3352{
3353 struct vm_page *pg; 3353 struct vm_page *pg;
3354 paddr_t pa; 3354 paddr_t pa;
3355 3355
3356 /* 3356 /*
3357 * Don't ask for a zero'd page in the L1PT case -- we will 3357 * Don't ask for a zero'd page in the L1PT case -- we will
3358 * properly initialize it in the constructor. 3358 * properly initialize it in the constructor.
3359 */ 3359 */
3360 3360
3361 pg = uvm_pagealloc(NULL, 0, NULL, usage == PGU_L1PT ? 3361 pg = uvm_pagealloc(NULL, 0, NULL, usage == PGU_L1PT ?
3362 UVM_PGA_USERESERVE : UVM_PGA_USERESERVE|UVM_PGA_ZERO); 3362 UVM_PGA_USERESERVE : UVM_PGA_USERESERVE|UVM_PGA_ZERO);
3363 if (pg != NULL) { 3363 if (pg != NULL) {
3364 pa = VM_PAGE_TO_PHYS(pg); 3364 pa = VM_PAGE_TO_PHYS(pg);
3365#ifdef DEBUG 3365#ifdef DEBUG
3366 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 3366 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
3367 if (md->pvh_refcnt != 0) { 3367 if (md->pvh_refcnt != 0) {
3368 printf("pmap_physpage_alloc: page 0x%lx has " 3368 printf("pmap_physpage_alloc: page 0x%lx has "
3369 "%d references\n", pa, md->pvh_refcnt); 3369 "%d references\n", pa, md->pvh_refcnt);
3370 panic("pmap_physpage_alloc"); 3370 panic("pmap_physpage_alloc");
3371 } 3371 }
3372#endif 3372#endif
3373 *pap = pa; 3373 *pap = pa;
3374 return (true); 3374 return (true);
3375 } 3375 }
3376 return (false); 3376 return (false);
3377} 3377}
3378 3378
3379/* 3379/*
3380 * pmap_physpage_free: 3380 * pmap_physpage_free:
3381 * 3381 *
3382 * Free the single page table page at the specified physical address. 3382 * Free the single page table page at the specified physical address.
3383 */ 3383 */
3384static void 3384static void
3385pmap_physpage_free(paddr_t pa) 3385pmap_physpage_free(paddr_t pa)
3386{ 3386{
3387 struct vm_page *pg; 3387 struct vm_page *pg;
3388 3388
3389 if ((pg = PHYS_TO_VM_PAGE(pa)) == NULL) 3389 if ((pg = PHYS_TO_VM_PAGE(pa)) == NULL)
3390 panic("pmap_physpage_free: bogus physical page address"); 3390 panic("pmap_physpage_free: bogus physical page address");
3391 3391
3392#ifdef DEBUG 3392#ifdef DEBUG
3393 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 3393 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
3394 if (md->pvh_refcnt != 0) 3394 if (md->pvh_refcnt != 0)
3395 panic("pmap_physpage_free: page still has references"); 3395 panic("pmap_physpage_free: page still has references");
3396#endif 3396#endif
3397 3397
3398 uvm_pagefree(pg); 3398 uvm_pagefree(pg);
3399} 3399}
3400 3400
3401/* 3401/*
3402 * pmap_physpage_addref: 3402 * pmap_physpage_addref:
3403 * 3403 *
3404 * Add a reference to the specified special use page. 3404 * Add a reference to the specified special use page.
3405 */ 3405 */
3406static int 3406static int
3407pmap_physpage_addref(void *kva) 3407pmap_physpage_addref(void *kva)
3408{ 3408{
3409 struct vm_page *pg; 3409 struct vm_page *pg;
3410 struct vm_page_md *md; 3410 struct vm_page_md *md;
3411 paddr_t pa; 3411 paddr_t pa;
3412 3412
3413 pa = ALPHA_K0SEG_TO_PHYS(trunc_page((vaddr_t)kva)); 3413 pa = ALPHA_K0SEG_TO_PHYS(trunc_page((vaddr_t)kva));
3414 pg = PHYS_TO_VM_PAGE(pa); 3414 pg = PHYS_TO_VM_PAGE(pa);
3415 md = VM_PAGE_TO_MD(pg); 3415 md = VM_PAGE_TO_MD(pg);
3416 3416
3417 KASSERT((int)md->pvh_refcnt >= 0); 3417 KASSERT((int)md->pvh_refcnt >= 0);
3418 3418
3419 return atomic_inc_uint_nv(&md->pvh_refcnt); 3419 return atomic_inc_uint_nv(&md->pvh_refcnt);
3420} 3420}
3421 3421
3422/* 3422/*
3423 * pmap_physpage_delref: 3423 * pmap_physpage_delref:
3424 * 3424 *
3425 * Delete a reference to the specified special use page. 3425 * Delete a reference to the specified special use page.
3426 */ 3426 */
3427static int 3427static int
3428pmap_physpage_delref(void *kva) 3428pmap_physpage_delref(void *kva)
3429{ 3429{
3430 struct vm_page *pg; 3430 struct vm_page *pg;
3431 struct vm_page_md *md; 3431 struct vm_page_md *md;
3432 paddr_t pa; 3432 paddr_t pa;
3433 3433
3434 pa = ALPHA_K0SEG_TO_PHYS(trunc_page((vaddr_t)kva)); 3434 pa = ALPHA_K0SEG_TO_PHYS(trunc_page((vaddr_t)kva));
3435 pg = PHYS_TO_VM_PAGE(pa); 3435 pg = PHYS_TO_VM_PAGE(pa);
3436 md = VM_PAGE_TO_MD(pg); 3436 md = VM_PAGE_TO_MD(pg);
3437 3437
3438 KASSERT((int)md->pvh_refcnt > 0); 3438 KASSERT((int)md->pvh_refcnt > 0);
3439 3439
3440 return atomic_dec_uint_nv(&md->pvh_refcnt); 3440 return atomic_dec_uint_nv(&md->pvh_refcnt);
3441} 3441}
3442 3442
3443/******************** page table page management ********************/ 3443/******************** page table page management ********************/
3444 3444
3445static bool 3445static bool
3446pmap_kptpage_alloc(paddr_t *pap) 3446pmap_kptpage_alloc(paddr_t *pap)
3447{ 3447{
3448 if (uvm.page_init_done == false) { 3448 if (uvm.page_init_done == false) {
3449 /* 3449 /*
3450 * We're growing the kernel pmap early (from 3450 * We're growing the kernel pmap early (from
3451 * uvm_pageboot_alloc()). This case must 3451 * uvm_pageboot_alloc()). This case must
3452 * be handled a little differently. 3452 * be handled a little differently.
3453 */ 3453 */
3454 *pap = ALPHA_K0SEG_TO_PHYS( 3454 *pap = ALPHA_K0SEG_TO_PHYS(
3455 pmap_steal_memory(PAGE_SIZE, NULL, NULL)); 3455 pmap_steal_memory(PAGE_SIZE, NULL, NULL));
3456 return true; 3456 return true;
3457 } 3457 }
3458 3458
3459 return pmap_physpage_alloc(PGU_NORMAL, pap); 3459 return pmap_physpage_alloc(PGU_NORMAL, pap);
3460} 3460}
3461 3461
3462/* 3462/*
3463 * pmap_growkernel: [ INTERFACE ] 3463 * pmap_growkernel: [ INTERFACE ]
3464 * 3464 *
3465 * Grow the kernel address space. This is a hint from the 3465 * Grow the kernel address space. This is a hint from the
3466 * upper layer to pre-allocate more kernel PT pages. 3466 * upper layer to pre-allocate more kernel PT pages.
3467 */ 3467 */
3468vaddr_t 3468vaddr_t
3469pmap_growkernel(vaddr_t maxkvaddr) 3469pmap_growkernel(vaddr_t maxkvaddr)
3470{ 3470{
3471 struct pmap *kpm = pmap_kernel(), *pm; 3471 struct pmap *kpm = pmap_kernel(), *pm;
3472 paddr_t ptaddr; 3472 paddr_t ptaddr;
3473 pt_entry_t *l1pte, *l2pte, pte; 3473 pt_entry_t *l1pte, *l2pte, pte;
3474 vaddr_t va; 3474 vaddr_t va;
3475 int l1idx; 3475 int l1idx;
3476 3476
3477 rw_enter(&pmap_growkernel_lock, RW_WRITER); 3477 rw_enter(&pmap_growkernel_lock, RW_WRITER);
3478 3478
3479 if (maxkvaddr <= virtual_end) 3479 if (maxkvaddr <= virtual_end)
3480 goto out; /* we are OK */ 3480 goto out; /* we are OK */
3481 3481
3482 va = virtual_end; 3482 va = virtual_end;
3483 3483
3484 while (va < maxkvaddr) { 3484 while (va < maxkvaddr) {
3485 /* 3485 /*
3486 * If there is no valid L1 PTE (i.e. no L2 PT page), 3486 * If there is no valid L1 PTE (i.e. no L2 PT page),
3487 * allocate a new L2 PT page and insert it into the 3487 * allocate a new L2 PT page and insert it into the
3488 * L1 map. 3488 * L1 map.
3489 */ 3489 */
3490 l1pte = pmap_l1pte(kpm, va); 3490 l1pte = pmap_l1pte(kpm, va);
3491 if (pmap_pte_v(l1pte) == 0) { 3491 if (pmap_pte_v(l1pte) == 0) {
3492 if (!pmap_kptpage_alloc(&ptaddr)) 3492 if (!pmap_kptpage_alloc(&ptaddr))
3493 goto die; 3493 goto die;
3494 pte = (atop(ptaddr) << PG_SHIFT) | 3494 pte = (atop(ptaddr) << PG_SHIFT) |
3495 PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED; 3495 PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;
3496 *l1pte = pte; 3496 *l1pte = pte;
3497 3497
3498 l1idx = l1pte_index(va); 3498 l1idx = l1pte_index(va);
3499 3499
3500 /* Update all the user pmaps. */ 3500 /* Update all the user pmaps. */
3501 mutex_enter(&pmap_all_pmaps_lock); 3501 mutex_enter(&pmap_all_pmaps_lock);
3502 for (pm = TAILQ_FIRST(&pmap_all_pmaps); 3502 for (pm = TAILQ_FIRST(&pmap_all_pmaps);
3503 pm != NULL; pm = TAILQ_NEXT(pm, pm_list)) { 3503 pm != NULL; pm = TAILQ_NEXT(pm, pm_list)) {
3504 /* Skip the kernel pmap. */ 3504 /* Skip the kernel pmap. */
3505 if (pm == pmap_kernel()) 3505 if (pm == pmap_kernel())
3506 continue; 3506 continue;
3507 3507
3508 /* 3508 /*
3509 * Any pmaps published on the global list 3509 * Any pmaps published on the global list
3510 * should never be referencing kernel_lev1map. 3510 * should never be referencing kernel_lev1map.
3511 */ 3511 */
3512 KASSERT(pm->pm_lev1map != kernel_lev1map); 3512 KASSERT(pm->pm_lev1map != kernel_lev1map);
3513 3513
3514 PMAP_LOCK(pm); 3514 PMAP_LOCK(pm);
3515 pm->pm_lev1map[l1idx] = pte; 3515 pm->pm_lev1map[l1idx] = pte;
3516 PMAP_UNLOCK(pm); 3516 PMAP_UNLOCK(pm);
3517 } 3517 }
3518 mutex_exit(&pmap_all_pmaps_lock); 3518 mutex_exit(&pmap_all_pmaps_lock);
3519 } 3519 }
3520 3520
3521 /* 3521 /*
3522 * Have an L2 PT page now, add the L3 PT page. 3522 * Have an L2 PT page now, add the L3 PT page.
3523 */ 3523 */
3524 l2pte = pmap_l2pte(kpm, va, l1pte); 3524 l2pte = pmap_l2pte(kpm, va, l1pte);
3525 KASSERT(pmap_pte_v(l2pte) == 0); 3525 KASSERT(pmap_pte_v(l2pte) == 0);
3526 if (!pmap_kptpage_alloc(&ptaddr)) 3526 if (!pmap_kptpage_alloc(&ptaddr))
3527 goto die; 3527 goto die;
3528 *l2pte = (atop(ptaddr) << PG_SHIFT) | 3528 *l2pte = (atop(ptaddr) << PG_SHIFT) |
3529 PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED; 3529 PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;
3530 va += ALPHA_L2SEG_SIZE; 3530 va += ALPHA_L2SEG_SIZE;
3531 } 3531 }
3532 3532
3533 /* Invalidate the L1 PT cache. */ 3533 /* Invalidate the L1 PT cache. */
3534 pool_cache_invalidate(&pmap_l1pt_cache); 3534 pool_cache_invalidate(&pmap_l1pt_cache);
3535 3535
3536 virtual_end = va; 3536 virtual_end = va;
3537 3537
3538 out: 3538 out:
3539 rw_exit(&pmap_growkernel_lock); 3539 rw_exit(&pmap_growkernel_lock);
3540 3540
3541 return (virtual_end); 3541 return (virtual_end);
3542 3542
3543 die: 3543 die:
3544 panic("pmap_growkernel: out of memory"); 3544 panic("pmap_growkernel: out of memory");
3545} 3545}
3546 3546
3547/* 3547/*
3548 * pmap_l1pt_ctor: 3548 * pmap_l1pt_ctor:
3549 * 3549 *
3550 * Pool cache constructor for L1 PT pages. 3550 * Pool cache constructor for L1 PT pages.
3551 * 3551 *
3552 * Note: The growkernel lock is held across allocations 3552 * Note: The growkernel lock is held across allocations
3553 * from our pool_cache, so we don't need to acquire it 3553 * from our pool_cache, so we don't need to acquire it
3554 * ourselves. 3554 * ourselves.
3555 */ 3555 */
3556static int 3556static int
3557pmap_l1pt_ctor(void *arg, void *object, int flags) 3557pmap_l1pt_ctor(void *arg, void *object, int flags)
3558{ 3558{
3559 pt_entry_t *l1pt = object, pte; 3559 pt_entry_t *l1pt = object, pte;
3560 int i; 3560 int i;
3561 3561
3562 /* 3562 /*
3563 * Initialize the new level 1 table by zeroing the 3563 * Initialize the new level 1 table by zeroing the
3564 * user portion and copying the kernel mappings into 3564 * user portion and copying the kernel mappings into
3565 * the kernel portion. 3565 * the kernel portion.
3566 */ 3566 */
3567 for (i = 0; i < l1pte_index(VM_MIN_KERNEL_ADDRESS); i++) 3567 for (i = 0; i < l1pte_index(VM_MIN_KERNEL_ADDRESS); i++)
3568 l1pt[i] = 0; 3568 l1pt[i] = 0;
3569 3569
3570 for (i = l1pte_index(VM_MIN_KERNEL_ADDRESS); 3570 for (i = l1pte_index(VM_MIN_KERNEL_ADDRESS);
3571 i <= l1pte_index(VM_MAX_KERNEL_ADDRESS); i++) 3571 i <= l1pte_index(VM_MAX_KERNEL_ADDRESS); i++)
3572 l1pt[i] = kernel_lev1map[i]; 3572 l1pt[i] = kernel_lev1map[i];
3573 3573
3574 /* 3574 /*
3575 * Now, map the new virtual page table. NOTE: NO ASM! 3575 * Now, map the new virtual page table. NOTE: NO ASM!
3576 */ 3576 */
3577 pte = ((ALPHA_K0SEG_TO_PHYS((vaddr_t) l1pt) >> PGSHIFT) << PG_SHIFT) | 3577 pte = ((ALPHA_K0SEG_TO_PHYS((vaddr_t) l1pt) >> PGSHIFT) << PG_SHIFT) |
3578 PG_V | PG_KRE | PG_KWE; 3578 PG_V | PG_KRE | PG_KWE;
3579 l1pt[l1pte_index(VPTBASE)] = pte; 3579 l1pt[l1pte_index(VPTBASE)] = pte;
3580 3580
3581 return (0); 3581 return (0);
3582} 3582}
3583 3583
3584/* 3584/*
3585 * pmap_l1pt_alloc: 3585 * pmap_l1pt_alloc:
3586 * 3586 *
3587 * Page alloctaor for L1 PT pages. 3587 * Page alloctaor for L1 PT pages.
3588 */ 3588 */
3589static void * 3589static void *
3590pmap_l1pt_alloc(struct pool *pp, int flags) 3590pmap_l1pt_alloc(struct pool *pp, int flags)
3591{ 3591{
3592 paddr_t ptpa; 3592 paddr_t ptpa;
3593 3593
3594 /* 3594 /*
3595 * Attempt to allocate a free page. 3595 * Attempt to allocate a free page.
3596 */ 3596 */
3597 if (pmap_physpage_alloc(PGU_L1PT, &ptpa) == false) 3597 if (pmap_physpage_alloc(PGU_L1PT, &ptpa) == false)
3598 return (NULL); 3598 return (NULL);
3599 3599
3600 return ((void *) ALPHA_PHYS_TO_K0SEG(ptpa)); 3600 return ((void *) ALPHA_PHYS_TO_K0SEG(ptpa));
3601} 3601}
3602 3602
3603/* 3603/*
3604 * pmap_l1pt_free: 3604 * pmap_l1pt_free:
3605 * 3605 *
3606 * Page freer for L1 PT pages. 3606 * Page freer for L1 PT pages.
3607 */ 3607 */
3608static void 3608static void
3609pmap_l1pt_free(struct pool *pp, void *v) 3609pmap_l1pt_free(struct pool *pp, void *v)
3610{ 3610{
3611 3611
3612 pmap_physpage_free(ALPHA_K0SEG_TO_PHYS((vaddr_t) v)); 3612 pmap_physpage_free(ALPHA_K0SEG_TO_PHYS((vaddr_t) v));
3613} 3613}
3614 3614
3615/* 3615/*
3616 * pmap_ptpage_alloc: 3616 * pmap_ptpage_alloc:
3617 * 3617 *
3618 * Allocate a level 2 or level 3 page table page for a user 3618 * Allocate a level 2 or level 3 page table page for a user
3619 * pmap, and initialize the PTE that references it. 3619 * pmap, and initialize the PTE that references it.
3620 * 3620 *
3621 * Note: the pmap must already be locked. 3621 * Note: the pmap must already be locked.
3622 */ 3622 */
3623static int 3623static int
3624pmap_ptpage_alloc(pt_entry_t * const pte, int const usage) 3624pmap_ptpage_alloc(pt_entry_t * const pte, int const usage)
3625{ 3625{
3626 paddr_t ptpa; 3626 paddr_t ptpa;
3627 3627
3628 /* 3628 /*
3629 * Allocate the page table page. 3629 * Allocate the page table page.
3630 */ 3630 */
3631 if (pmap_physpage_alloc(usage, &ptpa) == false) 3631 if (pmap_physpage_alloc(usage, &ptpa) == false)
3632 return (ENOMEM); 3632 return (ENOMEM);
3633 3633
3634 /* 3634 /*
3635 * Initialize the referencing PTE. 3635 * Initialize the referencing PTE.
3636 */ 3636 */
3637 const pt_entry_t npte = ((ptpa >> PGSHIFT) << PG_SHIFT) | 3637 const pt_entry_t npte = ((ptpa >> PGSHIFT) << PG_SHIFT) |
3638 PG_V | PG_KRE | PG_KWE | PG_WIRED; 3638 PG_V | PG_KRE | PG_KWE | PG_WIRED;
3639 3639
3640 atomic_store_relaxed(pte, npte); 3640 atomic_store_relaxed(pte, npte);
3641 3641
3642 return (0); 3642 return (0);
3643} 3643}
3644 3644
3645/* 3645/*
3646 * pmap_ptpage_free: 3646 * pmap_ptpage_free:
3647 * 3647 *
3648 * Free the level 2 or level 3 page table page referenced 3648 * Free the level 2 or level 3 page table page referenced
3649 * be the provided PTE. 3649 * be the provided PTE.
3650 * 3650 *
3651 * Note: the pmap must already be locked. 3651 * Note: the pmap must already be locked.
3652 */ 3652 */
3653static void 3653static void
3654pmap_ptpage_free(pt_entry_t * const pte, struct pmap_tlb_context * const tlbctx) 3654pmap_ptpage_free(pt_entry_t * const pte, struct pmap_tlb_context * const tlbctx)
3655{ 3655{
3656 3656
3657 /* 3657 /*
3658 * Extract the physical address of the page from the PTE 3658 * Extract the physical address of the page from the PTE
3659 * and clear the entry. 3659 * and clear the entry.
3660 */ 3660 */
3661 const paddr_t ptpa = pmap_pte_pa(pte); 3661 const paddr_t ptpa = pmap_pte_pa(pte);
3662 atomic_store_relaxed(pte, PG_NV); 3662 atomic_store_relaxed(pte, PG_NV);
3663 3663
3664#ifdef DEBUG 3664#ifdef DEBUG
3665 pmap_zero_page(ptpa); 3665 pmap_zero_page(ptpa);
3666#endif 3666#endif
3667 pmap_tlb_physpage_free(ptpa, tlbctx); 3667 pmap_tlb_physpage_free(ptpa, tlbctx);
3668} 3668}
3669 3669
3670/* 3670/*
3671 * pmap_l3pt_delref: 3671 * pmap_l3pt_delref:
3672 * 3672 *
3673 * Delete a reference on a level 3 PT page. If the reference drops 3673 * Delete a reference on a level 3 PT page. If the reference drops
3674 * to zero, free it. 3674 * to zero, free it.
3675 * 3675 *
3676 * Note: the pmap must already be locked. 3676 * Note: the pmap must already be locked.
3677 */ 3677 */
3678static void 3678static void
3679pmap_l3pt_delref(pmap_t pmap, vaddr_t va, pt_entry_t *l3pte, 3679pmap_l3pt_delref(pmap_t pmap, vaddr_t va, pt_entry_t *l3pte,
3680 struct pmap_tlb_context * const tlbctx) 3680 struct pmap_tlb_context * const tlbctx)
3681{ 3681{
3682 pt_entry_t *l1pte, *l2pte; 3682 pt_entry_t *l1pte, *l2pte;
3683 3683
3684 l1pte = pmap_l1pte(pmap, va); 3684 l1pte = pmap_l1pte(pmap, va);
3685 l2pte = pmap_l2pte(pmap, va, l1pte); 3685 l2pte = pmap_l2pte(pmap, va, l1pte);
3686 3686
3687#ifdef DIAGNOSTIC 3687#ifdef DIAGNOSTIC
3688 if (pmap == pmap_kernel()) 3688 if (pmap == pmap_kernel())
3689 panic("pmap_l3pt_delref: kernel pmap"); 3689 panic("pmap_l3pt_delref: kernel pmap");
3690#endif 3690#endif
3691 3691
3692 if (pmap_physpage_delref(l3pte) == 0) { 3692 if (pmap_physpage_delref(l3pte) == 0) {
3693 /* 3693 /*
3694 * No more mappings; we can free the level 3 table. 3694 * No more mappings; we can free the level 3 table.
3695 */ 3695 */
3696#ifdef DEBUG 3696#ifdef DEBUG
3697 if (pmapdebug & PDB_PTPAGE) 3697 if (pmapdebug & PDB_PTPAGE)
3698 printf("pmap_l3pt_delref: freeing level 3 table at " 3698 printf("pmap_l3pt_delref: freeing level 3 table at "
3699 "0x%lx\n", pmap_pte_pa(l2pte)); 3699 "0x%lx\n", pmap_pte_pa(l2pte));
3700#endif 3700#endif
3701 /* 3701 /*
3702 * You can pass NULL if you know the last refrence won't 3702 * You can pass NULL if you know the last refrence won't
3703 * be dropped. 3703 * be dropped.
3704 */ 3704 */
3705 KASSERT(tlbctx != NULL); 3705 KASSERT(tlbctx != NULL);
3706 pmap_ptpage_free(l2pte, tlbctx); 3706 pmap_ptpage_free(l2pte, tlbctx);
3707 3707
3708 /* 3708 /*
3709 * We've freed a level 3 table, so we must invalidate 3709 * We've freed a level 3 table, so we must invalidate
3710 * any now-stale TLB entries for the corresponding VPT 3710 * any now-stale TLB entries for the corresponding VPT
3711 * VA range. Easiest way to guarantee this is to hit 3711 * VA range. Easiest way to guarantee this is to hit
3712 * all of the user TLB entries. 3712 * all of the user TLB entries.
3713 */ 3713 */
3714 pmap_tlb_shootdown_all_user(pmap, PG_V, tlbctx); 3714 pmap_tlb_shootdown_all_user(pmap, PG_V, tlbctx);
3715 3715
3716 /* 3716 /*
3717 * We've freed a level 3 table, so delete the reference 3717 * We've freed a level 3 table, so delete the reference
3718 * on the level 2 table. 3718 * on the level 2 table.
3719 */ 3719 */
3720 pmap_l2pt_delref(pmap, l1pte, l2pte, tlbctx); 3720 pmap_l2pt_delref(pmap, l1pte, l2pte, tlbctx);
3721 } 3721 }
3722} 3722}
3723 3723
3724/* 3724/*
3725 * pmap_l2pt_delref: 3725 * pmap_l2pt_delref:
3726 * 3726 *
3727 * Delete a reference on a level 2 PT page. If the reference drops 3727 * Delete a reference on a level 2 PT page. If the reference drops
3728 * to zero, free it. 3728 * to zero, free it.
3729 * 3729 *
3730 * Note: the pmap must already be locked. 3730 * Note: the pmap must already be locked.
3731 */ 3731 */
3732static void 3732static void
3733pmap_l2pt_delref(pmap_t pmap, pt_entry_t *l1pte, pt_entry_t *l2pte, 3733pmap_l2pt_delref(pmap_t pmap, pt_entry_t *l1pte, pt_entry_t *l2pte,
3734 struct pmap_tlb_context * const tlbctx) 3734 struct pmap_tlb_context * const tlbctx)
3735{ 3735{
3736 3736
3737#ifdef DIAGNOSTIC 3737#ifdef DIAGNOSTIC
3738 if (pmap == pmap_kernel()) 3738 if (pmap == pmap_kernel())
3739 panic("pmap_l2pt_delref: kernel pmap"); 3739 panic("pmap_l2pt_delref: kernel pmap");
3740#endif 3740#endif
3741 3741
3742 if (pmap_physpage_delref(l2pte) == 0) { 3742 if (pmap_physpage_delref(l2pte) == 0) {
3743 /* 3743 /*
3744 * No more mappings in this segment; we can free the 3744 * No more mappings in this segment; we can free the
3745 * level 2 table. 3745 * level 2 table.
3746 */ 3746 */
3747#ifdef DEBUG 3747#ifdef DEBUG
3748 if (pmapdebug & PDB_PTPAGE) 3748 if (pmapdebug & PDB_PTPAGE)
3749 printf("pmap_l2pt_delref: freeing level 2 table at " 3749 printf("pmap_l2pt_delref: freeing level 2 table at "
3750 "0x%lx\n", pmap_pte_pa(l1pte)); 3750 "0x%lx\n", pmap_pte_pa(l1pte));
3751#endif 3751#endif
3752 /* 3752 /*
3753 * You can pass NULL if you know the last refrence won't 3753 * You can pass NULL if you know the last refrence won't
3754 * be dropped. 3754 * be dropped.
3755 */ 3755 */
3756 KASSERT(tlbctx != NULL); 3756 KASSERT(tlbctx != NULL);
3757 pmap_ptpage_free(l1pte, tlbctx); 3757 pmap_ptpage_free(l1pte, tlbctx);
3758 3758
3759 /* 3759 /*
3760 * We've freed a level 2 table, so we must invalidate 3760 * We've freed a level 2 table, so we must invalidate
3761 * any now-stale TLB entries for the corresponding VPT 3761 * any now-stale TLB entries for the corresponding VPT
3762 * VA range. Easiest way to guarantee this is to hit 3762 * VA range. Easiest way to guarantee this is to hit
3763 * all of the user TLB entries. 3763 * all of the user TLB entries.
3764 */ 3764 */
3765 pmap_tlb_shootdown_all_user(pmap, PG_V, tlbctx); 3765 pmap_tlb_shootdown_all_user(pmap, PG_V, tlbctx);
3766 3766
3767 /* 3767 /*
3768 * We've freed a level 2 table, so delete the reference 3768 * We've freed a level 2 table, so delete the reference
3769 * on the level 1 table. 3769 * on the level 1 table.
3770 */ 3770 */
3771 pmap_l1pt_delref(pmap, l1pte); 3771 pmap_l1pt_delref(pmap, l1pte);
3772 } 3772 }
3773} 3773}
3774 3774
3775/* 3775/*
3776 * pmap_l1pt_delref: 3776 * pmap_l1pt_delref:
3777 * 3777 *
3778 * Delete a reference on a level 1 PT page. 3778 * Delete a reference on a level 1 PT page.
3779 */ 3779 */
3780static void 3780static void
3781pmap_l1pt_delref(pmap_t pmap, pt_entry_t *l1pte) 3781pmap_l1pt_delref(pmap_t pmap, pt_entry_t *l1pte)
3782{ 3782{
3783 3783
3784 KASSERT(pmap != pmap_kernel()); 3784 KASSERT(pmap != pmap_kernel());
3785 3785
3786 (void)pmap_physpage_delref(l1pte); 3786 (void)pmap_physpage_delref(l1pte);
3787} 3787}
3788 3788
3789/******************** Address Space Number management ********************/ 3789/******************** Address Space Number management ********************/
3790 3790
3791/* 3791/*
3792 * pmap_asn_alloc: 3792 * pmap_asn_alloc:
3793 * 3793 *
3794 * Allocate and assign an ASN to the specified pmap. 3794 * Allocate and assign an ASN to the specified pmap.
3795 * 3795 *
3796 * Note: the pmap must already be locked. This may be called from 3796 * Note: the pmap must already be locked. This may be called from
3797 * an interprocessor interrupt, and in that case, the sender of 3797 * an interprocessor interrupt, and in that case, the sender of
3798 * the IPI has the pmap lock. 3798 * the IPI has the pmap lock.
3799 */ 3799 */
3800static u_int 3800static u_int
3801pmap_asn_alloc(pmap_t const pmap, struct cpu_info * const ci) 3801pmap_asn_alloc(pmap_t const pmap, struct cpu_info * const ci)
3802{ 3802{
3803 3803
3804#ifdef DEBUG 3804#ifdef DEBUG
3805 if (pmapdebug & (PDB_FOLLOW|PDB_ASN)) 3805 if (pmapdebug & (PDB_FOLLOW|PDB_ASN))
3806 printf("pmap_asn_alloc(%p)\n", pmap); 3806 printf("pmap_asn_alloc(%p)\n", pmap);
3807#endif 3807#endif
3808 3808
3809 KASSERT(pmap != pmap_kernel()); 3809 KASSERT(pmap != pmap_kernel());
3810 KASSERT(pmap->pm_lev1map != kernel_lev1map); 3810 KASSERT(pmap->pm_lev1map != kernel_lev1map);
3811 KASSERT(kpreempt_disabled()); 3811 KASSERT(kpreempt_disabled());
3812 3812
3813 /* No work to do if the the CPU does not implement ASNs. */ 3813 /* No work to do if the the CPU does not implement ASNs. */
3814 if (pmap_max_asn == 0) 3814 if (pmap_max_asn == 0)
3815 return 0; 3815 return 0;
3816 3816
3817 struct pmap_asn_info * const pma = &pmap->pm_asni[ci->ci_cpuid]; 3817 struct pmap_percpu * const pmc = &pmap->pm_percpu[ci->ci_cpuid];
3818 3818
3819 /* 3819 /*
3820 * Hopefully, we can continue using the one we have... 3820 * Hopefully, we can continue using the one we have...
3821 * 3821 *
3822 * N.B. the generation check will fail the first time 3822 * N.B. the generation check will fail the first time
3823 * any pmap is activated on a given CPU, because we start 3823 * any pmap is activated on a given CPU, because we start
3824 * the generation counter at 1, but initialize pmaps with 3824 * the generation counter at 1, but initialize pmaps with
3825 * 0; this forces the first ASN allocation to occur. 3825 * 0; this forces the first ASN allocation to occur.
3826 */ 3826 */
3827 if (pma->pma_asngen == ci->ci_asn_gen) { 3827 if (pmc->pmc_asngen == ci->ci_asn_gen) {
3828#ifdef DEBUG 3828#ifdef DEBUG
3829 if (pmapdebug & PDB_ASN) 3829 if (pmapdebug & PDB_ASN)
3830 printf("pmap_asn_alloc: same generation, keeping %u\n", 3830 printf("pmap_asn_alloc: same generation, keeping %u\n",
3831 pma->pma_asn); 3831 pmc->pmc_asn);
3832#endif 3832#endif
3833 TLB_COUNT(asn_reuse); 3833 TLB_COUNT(asn_reuse);
3834 return pma->pma_asn; 3834 return pmc->pmc_asn;
3835 } 3835 }
3836 3836
3837 /* 3837 /*
3838 * Need to assign a new ASN. Grab the next one, incrementing 3838 * Need to assign a new ASN. Grab the next one, incrementing
3839 * the generation number if we have to. 3839 * the generation number if we have to.
3840 */ 3840 */
3841 if (ci->ci_next_asn > pmap_max_asn) { 3841 if (ci->ci_next_asn > pmap_max_asn) {
3842 /* 3842 /*
3843 * Invalidate all non-PG_ASM TLB entries and the 3843 * Invalidate all non-PG_ASM TLB entries and the
3844 * I-cache, and bump the generation number. 3844 * I-cache, and bump the generation number.
3845 */ 3845 */
3846 ALPHA_TBIAP(); 3846 ALPHA_TBIAP();
3847 alpha_pal_imb(); 3847 alpha_pal_imb();
3848 3848
3849 ci->ci_next_asn = PMAP_ASN_FIRST_USER; 3849 ci->ci_next_asn = PMAP_ASN_FIRST_USER;
3850 ci->ci_asn_gen++; 3850 ci->ci_asn_gen++;
3851 TLB_COUNT(asn_newgen); 3851 TLB_COUNT(asn_newgen);
3852 3852
3853 /* 3853 /*
3854 * Make sure the generation number doesn't wrap. We could 3854 * Make sure the generation number doesn't wrap. We could
3855 * handle this scenario by traversing all of the pmaps, 3855 * handle this scenario by traversing all of the pmaps,
3856 * and invalidating the generation number on those which 3856 * and invalidating the generation number on those which
3857 * are not currently in use by this processor. 3857 * are not currently in use by this processor.
3858 * 3858 *
3859 * However... considering that we're using an unsigned 64-bit 3859 * However... considering that we're using an unsigned 64-bit
3860 * integer for generation numbers, on non-ASN CPUs, we won't 3860 * integer for generation numbers, on non-ASN CPUs, we won't
3861 * wrap for approximately 75 billion years on a 128-ASN CPU 3861 * wrap for approximately 75 billion years on a 128-ASN CPU
3862 * (assuming 1000 switch * operations per second). 3862 * (assuming 1000 switch * operations per second).
3863 * 3863 *
3864 * So, we don't bother. 3864 * So, we don't bother.
3865 */ 3865 */
3866 KASSERT(ci->ci_asn_gen != PMAP_ASNGEN_INVALID); 3866 KASSERT(ci->ci_asn_gen != PMAP_ASNGEN_INVALID);
3867#ifdef DEBUG 3867#ifdef DEBUG
3868 if (pmapdebug & PDB_ASN) 3868 if (pmapdebug & PDB_ASN)
3869 printf("pmap_asn_alloc: generation bumped to %lu\n", 3869 printf("pmap_asn_alloc: generation bumped to %lu\n",
3870 ci->ci_asn_ge); 3870 ci->ci_asn_ge);
3871#endif 3871#endif
3872 } 3872 }
3873 3873
3874 /* 3874 /*
3875 * Assign the new ASN and validate the generation number. 3875 * Assign the new ASN and validate the generation number.
3876 */ 3876 */
3877 pma->pma_asn = ci->ci_next_asn++; 3877 pmc->pmc_asn = ci->ci_next_asn++;
3878 pma->pma_asngen = ci->ci_asn_gen; 3878 pmc->pmc_asngen = ci->ci_asn_gen;
3879 TLB_COUNT(asn_assign); 3879 TLB_COUNT(asn_assign);
3880 3880
3881 /* 3881 /*
3882 * We have a new ASN, so we can skip any pending I-stream sync 3882 * We have a new ASN, so we can skip any pending I-stream sync
3883 * on the way back out to user space. 3883 * on the way back out to user space.
3884 */ 3884 */
3885 atomic_and_ulong(&pmap->pm_needisync, ~(1UL << ci->ci_cpuid)); 3885 atomic_and_ulong(&pmap->pm_needisync, ~(1UL << ci->ci_cpuid));
3886 3886
3887#ifdef DEBUG 3887#ifdef DEBUG
3888 if (pmapdebug & PDB_ASN) 3888 if (pmapdebug & PDB_ASN)
3889 printf("pmap_asn_alloc: assigning %u to pmap %p\n", 3889 printf("pmap_asn_alloc: assigning %u to pmap %p\n",
3890 pma->pma_asn, pmap); 3890 pmc->pmc_asn, pmap);
3891#endif 3891#endif
3892 return pma->pma_asn; 3892 return pmc->pmc_asn;
3893} 3893}

cvs diff -r1.85 -r1.86 src/sys/arch/alpha/include/pmap.h (switch to unified diff)

--- src/sys/arch/alpha/include/pmap.h 2021/05/24 03:43:24 1.85
+++ src/sys/arch/alpha/include/pmap.h 2021/05/29 21:54:51 1.86
@@ -1,355 +1,355 @@ @@ -1,355 +1,355 @@
1/* $NetBSD: pmap.h,v 1.85 2021/05/24 03:43:24 thorpej Exp $ */ 1/* $NetBSD: pmap.h,v 1.86 2021/05/29 21:54:51 thorpej Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1998, 1999, 2000, 2001, 2007 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 1999, 2000, 2001, 2007 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 Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center and by Chris G. Demetriou. 9 * NASA Ames Research Center and by Chris G. Demetriou.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33/* 33/*
34 * Copyright (c) 1991, 1993 34 * Copyright (c) 1991, 1993
35 * The Regents of the University of California. All rights reserved. 35 * The Regents of the University of California. All rights reserved.
36 * 36 *
37 * This code is derived from software contributed to Berkeley by 37 * This code is derived from software contributed to Berkeley by
38 * the Systems Programming Group of the University of Utah Computer 38 * the Systems Programming Group of the University of Utah Computer
39 * Science Department. 39 * Science Department.
40 * 40 *
41 * Redistribution and use in source and binary forms, with or without 41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions 42 * modification, are permitted provided that the following conditions
43 * are met: 43 * are met:
44 * 1. Redistributions of source code must retain the above copyright 44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer. 45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright 46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the 47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution. 48 * documentation and/or other materials provided with the distribution.
49 * 3. Neither the name of the University nor the names of its contributors 49 * 3. Neither the name of the University nor the names of its contributors
50 * may be used to endorse or promote products derived from this software 50 * may be used to endorse or promote products derived from this software
51 * without specific prior written permission. 51 * without specific prior written permission.
52 * 52 *
53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 * SUCH DAMAGE. 63 * SUCH DAMAGE.
64 * 64 *
65 * @(#)pmap.h 8.1 (Berkeley) 6/10/93 65 * @(#)pmap.h 8.1 (Berkeley) 6/10/93
66 */ 66 */
67 67
68/* 68/*
69 * Copyright (c) 1987 Carnegie-Mellon University 69 * Copyright (c) 1987 Carnegie-Mellon University
70 * 70 *
71 * This code is derived from software contributed to Berkeley by 71 * This code is derived from software contributed to Berkeley by
72 * the Systems Programming Group of the University of Utah Computer 72 * the Systems Programming Group of the University of Utah Computer
73 * Science Department. 73 * Science Department.
74 * 74 *
75 * Redistribution and use in source and binary forms, with or without 75 * Redistribution and use in source and binary forms, with or without
76 * modification, are permitted provided that the following conditions 76 * modification, are permitted provided that the following conditions
77 * are met: 77 * are met:
78 * 1. Redistributions of source code must retain the above copyright 78 * 1. Redistributions of source code must retain the above copyright
79 * notice, this list of conditions and the following disclaimer. 79 * notice, this list of conditions and the following disclaimer.
80 * 2. Redistributions in binary form must reproduce the above copyright 80 * 2. Redistributions in binary form must reproduce the above copyright
81 * notice, this list of conditions and the following disclaimer in the 81 * notice, this list of conditions and the following disclaimer in the
82 * documentation and/or other materials provided with the distribution. 82 * documentation and/or other materials provided with the distribution.
83 * 3. All advertising materials mentioning features or use of this software 83 * 3. All advertising materials mentioning features or use of this software
84 * must display the following acknowledgement: 84 * must display the following acknowledgement:
85 * This product includes software developed by the University of 85 * This product includes software developed by the University of
86 * California, Berkeley and its contributors. 86 * California, Berkeley and its contributors.
87 * 4. Neither the name of the University nor the names of its contributors 87 * 4. Neither the name of the University nor the names of its contributors
88 * may be used to endorse or promote products derived from this software 88 * may be used to endorse or promote products derived from this software
89 * without specific prior written permission. 89 * without specific prior written permission.
90 * 90 *
91 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 91 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
92 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 92 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
94 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 94 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
95 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 95 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
96 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 96 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
97 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 97 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
98 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 98 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
99 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 99 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
100 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 100 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
101 * SUCH DAMAGE. 101 * SUCH DAMAGE.
102 * 102 *
103 * @(#)pmap.h 8.1 (Berkeley) 6/10/93 103 * @(#)pmap.h 8.1 (Berkeley) 6/10/93
104 */ 104 */
105 105
106#ifndef _PMAP_MACHINE_ 106#ifndef _PMAP_MACHINE_
107#define _PMAP_MACHINE_ 107#define _PMAP_MACHINE_
108 108
109#if defined(_KERNEL_OPT) 109#if defined(_KERNEL_OPT)
110#include "opt_multiprocessor.h" 110#include "opt_multiprocessor.h"
111#endif 111#endif
112 112
113#include <sys/mutex.h> 113#include <sys/mutex.h>
114#include <sys/queue.h> 114#include <sys/queue.h>
115 115
116#include <machine/pte.h> 116#include <machine/pte.h>
117 117
118/* 118/*
119 * Machine-dependent virtual memory state. 119 * Machine-dependent virtual memory state.
120 * 120 *
121 * If we ever support processor numbers higher than 63, we'll have to 121 * If we ever support processor numbers higher than 63, we'll have to
122 * rethink the CPU mask. 122 * rethink the CPU mask.
123 * 123 *
124 * Note pm_asn and pm_asngen are arrays allocated in pmap_create(). 124 * Note pm_asn and pm_asngen are arrays allocated in pmap_create().
125 * Their size is based on the PCS count from the HWRPB, and indexed 125 * Their size is based on the PCS count from the HWRPB, and indexed
126 * by processor ID (from `whami'). This is all padded to COHERENCY_UNIT 126 * by processor ID (from `whami'). This is all padded to COHERENCY_UNIT
127 * to avoid false sharing. 127 * to avoid false sharing.
128 * 128 *
129 * The kernel pmap is a special case; since the kernel uses only ASM 129 * The kernel pmap is a special case; since the kernel uses only ASM
130 * mappings and uses a reserved ASN to keep the TLB clean, we don't 130 * mappings and uses a reserved ASN to keep the TLB clean, we don't
131 * allocate any ASN info for the kernel pmap at all. 131 * allocate any ASN info for the kernel pmap at all.
132 * arrays which hold enough for ALPHA_MAXPROCS. 132 * arrays which hold enough for ALPHA_MAXPROCS.
133 */ 133 */
134struct pmap_asn_info { 134struct pmap_percpu {
135 unsigned int pma_asn; /* address space number */ 135 unsigned int pmc_asn; /* address space number */
136 unsigned int pma_pad0; 136 unsigned int pmc_pad0;
137 unsigned long pma_asngen; /* ASN generation number */ 137 unsigned long pmc_asngen; /* ASN generation number */
138 unsigned long pma_padN[(COHERENCY_UNIT / 8) - 2]; 138 unsigned long pmc_padN[(COHERENCY_UNIT / 8) - 2];
139}; 139};
140 140
141struct pmap { /* pmaps are aligned to COHERENCY_UNIT boundaries */ 141struct pmap { /* pmaps are aligned to COHERENCY_UNIT boundaries */
142 /* pmaps are locked by hashed mutexes */ 142 /* pmaps are locked by hashed mutexes */
143 pt_entry_t *pm_lev1map; /* [ 0] level 1 map */ 143 pt_entry_t *pm_lev1map; /* [ 0] level 1 map */
144 unsigned long pm_cpus; /* [ 8] CPUs using pmap */ 144 unsigned long pm_cpus; /* [ 8] CPUs using pmap */
145 unsigned long pm_needisync; /* [16] CPUs needing isync */ 145 unsigned long pm_needisync; /* [16] CPUs needing isync */
146 struct pmap_statistics pm_stats; /* [32] statistics */ 146 struct pmap_statistics pm_stats; /* [32] statistics */
147 unsigned int pm_count; /* [40] reference count */ 147 unsigned int pm_count; /* [40] reference count */
148 unsigned int __pm_spare; /* [44] spare field */ 148 unsigned int __pm_spare; /* [44] spare field */
149 TAILQ_ENTRY(pmap) pm_list; /* [48] list of all pmaps */ 149 TAILQ_ENTRY(pmap) pm_list; /* [48] list of all pmaps */
150 /* -- COHERENCY_UNIT boundary -- */ 150 /* -- COHERENCY_UNIT boundary -- */
151 struct pmap_asn_info pm_asni[]; /* [64] ASN information */ 151 struct pmap_percpu pm_percpu[]; /* [64] per-CPU data */
152 /* variable length */ 152 /* variable length */
153}; 153};
154 154
155#define PMAP_SIZEOF(x) \ 155#define PMAP_SIZEOF(x) \
156 (ALIGN(offsetof(struct pmap, pm_asni[(x)]))) 156 (ALIGN(offsetof(struct pmap, pm_percpu[(x)])))
157 157
158#define PMAP_ASN_KERNEL 0 /* kernel-reserved ASN */ 158#define PMAP_ASN_KERNEL 0 /* kernel-reserved ASN */
159#define PMAP_ASN_FIRST_USER 1 /* first user ASN */ 159#define PMAP_ASN_FIRST_USER 1 /* first user ASN */
160#define PMAP_ASNGEN_INVALID 0 /* reserved (invalid) ASN generation */ 160#define PMAP_ASNGEN_INVALID 0 /* reserved (invalid) ASN generation */
161#define PMAP_ASNGEN_INITIAL 1 /* first valid generatation */ 161#define PMAP_ASNGEN_INITIAL 1 /* first valid generatation */
162 162
163/* 163/*
164 * For each struct vm_page, there is a list of all currently valid virtual 164 * For each struct vm_page, there is a list of all currently valid virtual
165 * mappings of that page. An entry is a pv_entry_t, the list is pv_table. 165 * mappings of that page. An entry is a pv_entry_t, the list is pv_table.
166 */ 166 */
167typedef struct pv_entry { 167typedef struct pv_entry {
168 struct pv_entry *pv_next; /* next pv_entry on list */ 168 struct pv_entry *pv_next; /* next pv_entry on list */
169 struct pmap *pv_pmap; /* pmap where mapping lies */ 169 struct pmap *pv_pmap; /* pmap where mapping lies */
170 vaddr_t pv_va; /* virtual address for mapping */ 170 vaddr_t pv_va; /* virtual address for mapping */
171 pt_entry_t *pv_pte; /* PTE that maps the VA */ 171 pt_entry_t *pv_pte; /* PTE that maps the VA */
172} *pv_entry_t; 172} *pv_entry_t;
173 173
174/* pvh_attrs */ 174/* pvh_attrs */
175#define PGA_MODIFIED 0x01 /* modified */ 175#define PGA_MODIFIED 0x01 /* modified */
176#define PGA_REFERENCED 0x02 /* referenced */ 176#define PGA_REFERENCED 0x02 /* referenced */
177 177
178/* pvh_usage */ 178/* pvh_usage */
179#define PGU_NORMAL 0 /* free or normal use */ 179#define PGU_NORMAL 0 /* free or normal use */
180#define PGU_PVENT 1 /* PV entries */ 180#define PGU_PVENT 1 /* PV entries */
181#define PGU_L1PT 2 /* level 1 page table */ 181#define PGU_L1PT 2 /* level 1 page table */
182#define PGU_L2PT 3 /* level 2 page table */ 182#define PGU_L2PT 3 /* level 2 page table */
183#define PGU_L3PT 4 /* level 3 page table */ 183#define PGU_L3PT 4 /* level 3 page table */
184 184
185#ifdef _KERNEL 185#ifdef _KERNEL
186 186
187#include <sys/atomic.h> 187#include <sys/atomic.h>
188 188
189struct cpu_info; 189struct cpu_info;
190struct trapframe; 190struct trapframe;
191 191
192void pmap_init_cpu(struct cpu_info *); 192void pmap_init_cpu(struct cpu_info *);
193#if defined(MULTIPROCESSOR) 193#if defined(MULTIPROCESSOR)
194void pmap_tlb_shootdown_ipi(struct cpu_info *, struct trapframe *); 194void pmap_tlb_shootdown_ipi(struct cpu_info *, struct trapframe *);
195#endif /* MULTIPROCESSOR */ 195#endif /* MULTIPROCESSOR */
196 196
197#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count) 197#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count)
198#define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count) 198#define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count)
199 199
200#define pmap_copy(dp, sp, da, l, sa) /* nothing */ 200#define pmap_copy(dp, sp, da, l, sa) /* nothing */
201#define pmap_update(pmap) /* nothing (yet) */ 201#define pmap_update(pmap) /* nothing (yet) */
202 202
203static __inline bool 203static __inline bool
204pmap_remove_all(struct pmap *pmap) 204pmap_remove_all(struct pmap *pmap)
205{ 205{
206 /* Nothing. */ 206 /* Nothing. */
207 return false; 207 return false;
208} 208}
209 209
210#define pmap_is_referenced(pg) \ 210#define pmap_is_referenced(pg) \
211 (((pg)->mdpage.pvh_attrs & PGA_REFERENCED) != 0) 211 (((pg)->mdpage.pvh_attrs & PGA_REFERENCED) != 0)
212#define pmap_is_modified(pg) \ 212#define pmap_is_modified(pg) \
213 (((pg)->mdpage.pvh_attrs & PGA_MODIFIED) != 0) 213 (((pg)->mdpage.pvh_attrs & PGA_MODIFIED) != 0)
214 214
215#define PMAP_STEAL_MEMORY /* enable pmap_steal_memory() */ 215#define PMAP_STEAL_MEMORY /* enable pmap_steal_memory() */
216#define PMAP_GROWKERNEL /* enable pmap_growkernel() */ 216#define PMAP_GROWKERNEL /* enable pmap_growkernel() */
217 217
218#define PMAP_DIRECT 218#define PMAP_DIRECT
219#define PMAP_DIRECT_MAP(pa) ALPHA_PHYS_TO_K0SEG((pa)) 219#define PMAP_DIRECT_MAP(pa) ALPHA_PHYS_TO_K0SEG((pa))
220#define PMAP_DIRECT_UNMAP(va) ALPHA_K0SEG_TO_PHYS((va)) 220#define PMAP_DIRECT_UNMAP(va) ALPHA_K0SEG_TO_PHYS((va))
221 221
222static __inline int 222static __inline int
223pmap_direct_process(paddr_t pa, voff_t pgoff, size_t len, 223pmap_direct_process(paddr_t pa, voff_t pgoff, size_t len,
224 int (*process)(void *, size_t, void *), void *arg) 224 int (*process)(void *, size_t, void *), void *arg)
225{ 225{
226 vaddr_t va = PMAP_DIRECT_MAP(pa); 226 vaddr_t va = PMAP_DIRECT_MAP(pa);
227 227
228 return process((void *)(va + pgoff), len, arg); 228 return process((void *)(va + pgoff), len, arg);
229} 229}
230 230
231/* 231/*
232 * Alternate mapping hooks for pool pages. Avoids thrashing the TLB. 232 * Alternate mapping hooks for pool pages. Avoids thrashing the TLB.
233 */ 233 */
234#define PMAP_MAP_POOLPAGE(pa) PMAP_DIRECT_MAP(pa) 234#define PMAP_MAP_POOLPAGE(pa) PMAP_DIRECT_MAP(pa)
235#define PMAP_UNMAP_POOLPAGE(va) PMAP_DIRECT_UNMAP(va) 235#define PMAP_UNMAP_POOLPAGE(va) PMAP_DIRECT_UNMAP(va)
236 236
237/* 237/*
238 * Other hooks for the pool allocator. 238 * Other hooks for the pool allocator.
239 */ 239 */
240#define POOL_VTOPHYS(va) ALPHA_K0SEG_TO_PHYS((vaddr_t) (va)) 240#define POOL_VTOPHYS(va) ALPHA_K0SEG_TO_PHYS((vaddr_t) (va))
241 241
242bool pmap_pageidlezero(paddr_t); 242bool pmap_pageidlezero(paddr_t);
243#define PMAP_PAGEIDLEZERO(pa) pmap_pageidlezero((pa)) 243#define PMAP_PAGEIDLEZERO(pa) pmap_pageidlezero((pa))
244 244
245paddr_t vtophys(vaddr_t); 245paddr_t vtophys(vaddr_t);
246 246
247/* Machine-specific functions. */ 247/* Machine-specific functions. */
248void pmap_bootstrap(paddr_t, u_int, u_long); 248void pmap_bootstrap(paddr_t, u_int, u_long);
249int pmap_emulate_reference(struct lwp *, vaddr_t, int, int); 249int pmap_emulate_reference(struct lwp *, vaddr_t, int, int);
250 250
251#define pmap_pte_pa(pte) (PG_PFNUM(*(pte)) << PGSHIFT) 251#define pmap_pte_pa(pte) (PG_PFNUM(*(pte)) << PGSHIFT)
252#define pmap_pte_prot(pte) (*(pte) & PG_PROT) 252#define pmap_pte_prot(pte) (*(pte) & PG_PROT)
253#define pmap_pte_w(pte) (*(pte) & PG_WIRED) 253#define pmap_pte_w(pte) (*(pte) & PG_WIRED)
254#define pmap_pte_v(pte) (*(pte) & PG_V) 254#define pmap_pte_v(pte) (*(pte) & PG_V)
255#define pmap_pte_pv(pte) (*(pte) & PG_PVLIST) 255#define pmap_pte_pv(pte) (*(pte) & PG_PVLIST)
256#define pmap_pte_asm(pte) (*(pte) & PG_ASM) 256#define pmap_pte_asm(pte) (*(pte) & PG_ASM)
257#define pmap_pte_exec(pte) (*(pte) & PG_EXEC) 257#define pmap_pte_exec(pte) (*(pte) & PG_EXEC)
258 258
259#define pmap_pte_set_w(pte, v) \ 259#define pmap_pte_set_w(pte, v) \
260do { \ 260do { \
261 if (v) \ 261 if (v) \
262 *(pte) |= PG_WIRED; \ 262 *(pte) |= PG_WIRED; \
263 else \ 263 else \
264 *(pte) &= ~PG_WIRED; \ 264 *(pte) &= ~PG_WIRED; \
265} while (0) 265} while (0)
266 266
267#define pmap_pte_w_chg(pte, nw) ((nw) ^ pmap_pte_w(pte)) 267#define pmap_pte_w_chg(pte, nw) ((nw) ^ pmap_pte_w(pte))
268 268
269#define pmap_pte_set_prot(pte, np) \ 269#define pmap_pte_set_prot(pte, np) \
270do { \ 270do { \
271 *(pte) &= ~PG_PROT; \ 271 *(pte) &= ~PG_PROT; \
272 *(pte) |= (np); \ 272 *(pte) |= (np); \
273} while (0) 273} while (0)
274 274
275#define pmap_pte_prot_chg(pte, np) ((np) ^ pmap_pte_prot(pte)) 275#define pmap_pte_prot_chg(pte, np) ((np) ^ pmap_pte_prot(pte))
276 276
277static __inline pt_entry_t * 277static __inline pt_entry_t *
278pmap_l1pte(pmap_t pmap, vaddr_t v) 278pmap_l1pte(pmap_t pmap, vaddr_t v)
279{ 279{
280 KASSERT(pmap->pm_lev1map != NULL); 280 KASSERT(pmap->pm_lev1map != NULL);
281 return &pmap->pm_lev1map[l1pte_index(v)]; 281 return &pmap->pm_lev1map[l1pte_index(v)];
282} 282}
283 283
284static __inline pt_entry_t * 284static __inline pt_entry_t *
285pmap_l2pte(pmap_t pmap, vaddr_t v, pt_entry_t *l1pte) 285pmap_l2pte(pmap_t pmap, vaddr_t v, pt_entry_t *l1pte)
286{ 286{
287 pt_entry_t *lev2map; 287 pt_entry_t *lev2map;
288 288
289 if (l1pte == NULL) { 289 if (l1pte == NULL) {
290 l1pte = pmap_l1pte(pmap, v); 290 l1pte = pmap_l1pte(pmap, v);
291 if (pmap_pte_v(l1pte) == 0) 291 if (pmap_pte_v(l1pte) == 0)
292 return NULL; 292 return NULL;
293 } 293 }
294 294
295 lev2map = (pt_entry_t *)ALPHA_PHYS_TO_K0SEG(pmap_pte_pa(l1pte)); 295 lev2map = (pt_entry_t *)ALPHA_PHYS_TO_K0SEG(pmap_pte_pa(l1pte));
296 return &lev2map[l2pte_index(v)]; 296 return &lev2map[l2pte_index(v)];
297} 297}
298 298
299static __inline pt_entry_t * 299static __inline pt_entry_t *
300pmap_l3pte(pmap_t pmap, vaddr_t v, pt_entry_t *l2pte) 300pmap_l3pte(pmap_t pmap, vaddr_t v, pt_entry_t *l2pte)
301{ 301{
302 pt_entry_t *l1pte, *lev2map, *lev3map; 302 pt_entry_t *l1pte, *lev2map, *lev3map;
303 303
304 if (l2pte == NULL) { 304 if (l2pte == NULL) {
305 l1pte = pmap_l1pte(pmap, v); 305 l1pte = pmap_l1pte(pmap, v);
306 if (pmap_pte_v(l1pte) == 0) 306 if (pmap_pte_v(l1pte) == 0)
307 return NULL; 307 return NULL;
308 308
309 lev2map = (pt_entry_t *)ALPHA_PHYS_TO_K0SEG(pmap_pte_pa(l1pte)); 309 lev2map = (pt_entry_t *)ALPHA_PHYS_TO_K0SEG(pmap_pte_pa(l1pte));
310 l2pte = &lev2map[l2pte_index(v)]; 310 l2pte = &lev2map[l2pte_index(v)];
311 if (pmap_pte_v(l2pte) == 0) 311 if (pmap_pte_v(l2pte) == 0)
312 return NULL; 312 return NULL;
313 } 313 }
314 314
315 lev3map = (pt_entry_t *)ALPHA_PHYS_TO_K0SEG(pmap_pte_pa(l2pte)); 315 lev3map = (pt_entry_t *)ALPHA_PHYS_TO_K0SEG(pmap_pte_pa(l2pte));
316 return &lev3map[l3pte_index(v)]; 316 return &lev3map[l3pte_index(v)];
317} 317}
318 318
319/* 319/*
320 * Macro for processing deferred I-stream synchronization. 320 * Macro for processing deferred I-stream synchronization.
321 * 321 *
322 * The pmap module may defer syncing the user I-stream until the 322 * The pmap module may defer syncing the user I-stream until the
323 * return to userspace, since the IMB PALcode op can be quite 323 * return to userspace, since the IMB PALcode op can be quite
324 * expensive. Since user instructions won't be executed until 324 * expensive. Since user instructions won't be executed until
325 * the return to userspace, this can be deferred until userret(). 325 * the return to userspace, this can be deferred until userret().
326 */ 326 */
327#define PMAP_USERRET(pmap) \ 327#define PMAP_USERRET(pmap) \
328do { \ 328do { \
329 u_long cpu_mask = (1UL << cpu_number()); \ 329 u_long cpu_mask = (1UL << cpu_number()); \
330 \ 330 \
331 if ((pmap)->pm_needisync & cpu_mask) { \ 331 if ((pmap)->pm_needisync & cpu_mask) { \
332 atomic_and_ulong(&(pmap)->pm_needisync, ~cpu_mask); \ 332 atomic_and_ulong(&(pmap)->pm_needisync, ~cpu_mask); \
333 alpha_pal_imb(); \ 333 alpha_pal_imb(); \
334 } \ 334 } \
335} while (0) 335} while (0)
336 336
337/* 337/*
338 * pmap-specific data store in the vm_page structure. 338 * pmap-specific data store in the vm_page structure.
339 */ 339 */
340#define __HAVE_VM_PAGE_MD 340#define __HAVE_VM_PAGE_MD
341struct vm_page_md { 341struct vm_page_md {
342 struct pv_entry *pvh_list; /* pv_entry list */ 342 struct pv_entry *pvh_list; /* pv_entry list */
343 int pvh_attrs; /* page attributes */ 343 int pvh_attrs; /* page attributes */
344 unsigned pvh_refcnt; 344 unsigned pvh_refcnt;
345}; 345};
346 346
347#define VM_MDPAGE_INIT(pg) \ 347#define VM_MDPAGE_INIT(pg) \
348do { \ 348do { \
349 (pg)->mdpage.pvh_list = NULL; \ 349 (pg)->mdpage.pvh_list = NULL; \
350 (pg)->mdpage.pvh_refcnt = 0; \ 350 (pg)->mdpage.pvh_refcnt = 0; \
351} while (/*CONSTCOND*/0) 351} while (/*CONSTCOND*/0)
352 352
353#endif /* _KERNEL */ 353#endif /* _KERNEL */
354 354
355#endif /* _PMAP_MACHINE_ */ 355#endif /* _PMAP_MACHINE_ */