Sun May 30 19:50:23 2021 UTC ()
Fix DEBUG build.


(thorpej)
diff -r1.291 -r1.292 src/sys/arch/alpha/alpha/pmap.c

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

--- src/sys/arch/alpha/alpha/pmap.c 2021/05/30 19:46:21 1.291
+++ src/sys/arch/alpha/alpha/pmap.c 2021/05/30 19:50:23 1.292
@@ -1,4030 +1,4027 @@ @@ -1,4030 +1,4027 @@
1/* $NetBSD: pmap.c,v 1.291 2021/05/30 19:46:21 thorpej Exp $ */ 1/* $NetBSD: pmap.c,v 1.292 2021/05/30 19:50:23 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.291 2021/05/30 19:46:21 thorpej Exp $"); 138__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.292 2021/05/30 19:50:23 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_percpu[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_percpu) == 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 context structure; see description in "TLB management" section 435 * TLB context structure; see description in "TLB management" section
436 * below. 436 * below.
437 */ 437 */
438#define TLB_CTX_MAXVA 8 438#define TLB_CTX_MAXVA 8
439#define TLB_CTX_ALLVA PAGE_MASK 439#define TLB_CTX_ALLVA PAGE_MASK
440struct pmap_tlb_context { 440struct pmap_tlb_context {
441 uintptr_t t_addrdata[TLB_CTX_MAXVA]; 441 uintptr_t t_addrdata[TLB_CTX_MAXVA];
442 pmap_t t_pmap; 442 pmap_t t_pmap;
443 struct pmap_pagelist t_freeptq; 443 struct pmap_pagelist t_freeptq;
444 struct pmap_pvlist t_freepvq; 444 struct pmap_pvlist t_freepvq;
445}; 445};
446 446
447/* 447/*
448 * Internal routines 448 * Internal routines
449 */ 449 */
450static void alpha_protection_init(void); 450static void alpha_protection_init(void);
451static pt_entry_t pmap_remove_mapping(pmap_t, vaddr_t, pt_entry_t *, bool, 451static pt_entry_t pmap_remove_mapping(pmap_t, vaddr_t, pt_entry_t *, bool,
452 pv_entry_t *, 452 pv_entry_t *,
453 struct pmap_tlb_context *); 453 struct pmap_tlb_context *);
454static void pmap_changebit(struct vm_page *, pt_entry_t, pt_entry_t, 454static void pmap_changebit(struct vm_page *, pt_entry_t, pt_entry_t,
455 struct pmap_tlb_context *); 455 struct pmap_tlb_context *);
456 456
457/* 457/*
458 * PT page management functions. 458 * PT page management functions.
459 */ 459 */
460static int pmap_ptpage_alloc(pmap_t, pt_entry_t *, int); 460static int pmap_ptpage_alloc(pmap_t, pt_entry_t *, int);
461static void pmap_ptpage_free(pmap_t, pt_entry_t *, 461static void pmap_ptpage_free(pmap_t, pt_entry_t *,
462 struct pmap_tlb_context *); 462 struct pmap_tlb_context *);
463static void pmap_l3pt_delref(pmap_t, vaddr_t, pt_entry_t *, 463static void pmap_l3pt_delref(pmap_t, vaddr_t, pt_entry_t *,
464 struct pmap_tlb_context *); 464 struct pmap_tlb_context *);
465static void pmap_l2pt_delref(pmap_t, pt_entry_t *, pt_entry_t *, 465static void pmap_l2pt_delref(pmap_t, pt_entry_t *, pt_entry_t *,
466 struct pmap_tlb_context *); 466 struct pmap_tlb_context *);
467static void pmap_l1pt_delref(pmap_t, pt_entry_t *); 467static void pmap_l1pt_delref(pmap_t, pt_entry_t *);
468 468
469static void *pmap_l1pt_alloc(struct pool *, int); 469static void *pmap_l1pt_alloc(struct pool *, int);
470static void pmap_l1pt_free(struct pool *, void *); 470static void pmap_l1pt_free(struct pool *, void *);
471 471
472static struct pool_allocator pmap_l1pt_allocator = { 472static struct pool_allocator pmap_l1pt_allocator = {
473 pmap_l1pt_alloc, pmap_l1pt_free, 0, 473 pmap_l1pt_alloc, pmap_l1pt_free, 0,
474}; 474};
475 475
476static int pmap_l1pt_ctor(void *, void *, int); 476static int pmap_l1pt_ctor(void *, void *, int);
477 477
478/* 478/*
479 * PV table management functions. 479 * PV table management functions.
480 */ 480 */
481static int pmap_pv_enter(pmap_t, struct vm_page *, vaddr_t, pt_entry_t *, 481static int pmap_pv_enter(pmap_t, struct vm_page *, vaddr_t, pt_entry_t *,
482 bool, pv_entry_t); 482 bool, pv_entry_t);
483static void pmap_pv_remove(pmap_t, struct vm_page *, vaddr_t, bool, 483static void pmap_pv_remove(pmap_t, struct vm_page *, vaddr_t, bool,
484 pv_entry_t *, struct pmap_tlb_context *); 484 pv_entry_t *, struct pmap_tlb_context *);
485static void *pmap_pv_page_alloc(struct pool *, int); 485static void *pmap_pv_page_alloc(struct pool *, int);
486static void pmap_pv_page_free(struct pool *, void *); 486static void pmap_pv_page_free(struct pool *, void *);
487 487
488static struct pool_allocator pmap_pv_page_allocator = { 488static struct pool_allocator pmap_pv_page_allocator = {
489 pmap_pv_page_alloc, pmap_pv_page_free, 0, 489 pmap_pv_page_alloc, pmap_pv_page_free, 0,
490}; 490};
491 491
492#ifdef DEBUG 492#ifdef DEBUG
493void pmap_pv_dump(paddr_t); 493void pmap_pv_dump(paddr_t);
494#endif 494#endif
495 495
496#define pmap_pv_alloc() pool_cache_get(&pmap_pv_cache, PR_NOWAIT) 496#define pmap_pv_alloc() pool_cache_get(&pmap_pv_cache, PR_NOWAIT)
497#define pmap_pv_free(pv) pool_cache_put(&pmap_pv_cache, (pv)) 497#define pmap_pv_free(pv) pool_cache_put(&pmap_pv_cache, (pv))
498 498
499/* 499/*
500 * Generic routine for freeing pages on a pmap_pagelist back to 500 * Generic routine for freeing pages on a pmap_pagelist back to
501 * the system. 501 * the system.
502 */ 502 */
503static void 503static void
504pmap_pagelist_free(struct pmap_pagelist * const list) 504pmap_pagelist_free(struct pmap_pagelist * const list)
505{ 505{
506 struct vm_page *pg; 506 struct vm_page *pg;
507 507
508 while ((pg = LIST_FIRST(list)) != NULL) { 508 while ((pg = LIST_FIRST(list)) != NULL) {
509 LIST_REMOVE(pg, pageq.list); 509 LIST_REMOVE(pg, pageq.list);
510 /* Zap any fields we used internally. */ 510 /* Zap any fields we used internally. */
511 atomic_store_relaxed(&pg->loan_count, 0); 511 atomic_store_relaxed(&pg->loan_count, 0);
512 uvm_pagefree(pg); 512 uvm_pagefree(pg);
513 } 513 }
514} 514}
515 515
516/* 516/*
517 * Generic routine for freeing a list of PV entries back to the 517 * Generic routine for freeing a list of PV entries back to the
518 * system. 518 * system.
519 */ 519 */
520static void 520static void
521pmap_pvlist_free(struct pmap_pvlist * const list) 521pmap_pvlist_free(struct pmap_pvlist * const list)
522{ 522{
523 pv_entry_t pv; 523 pv_entry_t pv;
524 524
525 while ((pv = LIST_FIRST(list)) != NULL) { 525 while ((pv = LIST_FIRST(list)) != NULL) {
526 LIST_REMOVE(pv, pv_link); 526 LIST_REMOVE(pv, pv_link);
527 pmap_pv_free(pv); 527 pmap_pv_free(pv);
528 } 528 }
529} 529}
530 530
531/* 531/*
532 * TLB management. 532 * TLB management.
533 * 533 *
534 * TLB invalidations need to be performed on local and remote CPUs 534 * TLB invalidations need to be performed on local and remote CPUs
535 * whenever parts of the PTE that the hardware or PALcode understands 535 * whenever parts of the PTE that the hardware or PALcode understands
536 * changes. In order amortize the cost of these operations, we will 536 * changes. In order amortize the cost of these operations, we will
537 * queue up to 8 addresses to invalidate in a batch. Any more than 537 * queue up to 8 addresses to invalidate in a batch. Any more than
538 * that, and we will hit the entire TLB. 538 * that, and we will hit the entire TLB.
539 * 539 *
540 * Some things that add complexity: 540 * Some things that add complexity:
541 * 541 *
542 * ==> ASNs. A CPU may have valid TLB entries for other than the current 542 * ==> ASNs. A CPU may have valid TLB entries for other than the current
543 * address spaace. We can only invalidate TLB entries for the current 543 * address spaace. We can only invalidate TLB entries for the current
544 * address space, so when asked to invalidate a VA for the non-current 544 * address space, so when asked to invalidate a VA for the non-current
545 * pmap on a given CPU, we simply invalidate the ASN for that pmap,CPU 545 * pmap on a given CPU, we simply invalidate the ASN for that pmap,CPU
546 * tuple so that new one is allocated on the next activation on that 546 * tuple so that new one is allocated on the next activation on that
547 * CPU. N.B. that for CPUs that don't implement ASNs, SWPCTX does all 547 * CPU. N.B. that for CPUs that don't implement ASNs, SWPCTX does all
548 * the work necessary, so we can skip some work in the pmap module 548 * the work necessary, so we can skip some work in the pmap module
549 * itself. 549 * itself.
550 * 550 *
551 * When a pmap is activated on a given CPU, we set a corresponding 551 * When a pmap is activated on a given CPU, we set a corresponding
552 * bit in pmap::pm_cpus, indicating that it potentially has valid 552 * bit in pmap::pm_cpus, indicating that it potentially has valid
553 * TLB entries for that address space. This bitmap is then used to 553 * TLB entries for that address space. This bitmap is then used to
554 * determine which remote CPUs need to be notified of invalidations. 554 * determine which remote CPUs need to be notified of invalidations.
555 * The bit is cleared when the ASN is invalidated on that CPU. 555 * The bit is cleared when the ASN is invalidated on that CPU.
556 * 556 *
557 * In order to serialize with activating an address space on a 557 * In order to serialize with activating an address space on a
558 * given CPU (that we can reliably send notifications only to 558 * given CPU (that we can reliably send notifications only to
559 * relevant remote CPUs), we acquire the pmap lock in pmap_activate() 559 * relevant remote CPUs), we acquire the pmap lock in pmap_activate()
560 * and also hold the lock while remote shootdowns take place. 560 * and also hold the lock while remote shootdowns take place.
561 * This does not apply to the kernel pmap; all CPUs are notified about 561 * This does not apply to the kernel pmap; all CPUs are notified about
562 * invalidations for the kernel pmap, and the pmap lock is not held 562 * invalidations for the kernel pmap, and the pmap lock is not held
563 * in pmap_activate() for the kernel pmap. 563 * in pmap_activate() for the kernel pmap.
564 * 564 *
565 * ==> P->V operations (e.g. pmap_page_protect()) may require sending 565 * ==> P->V operations (e.g. pmap_page_protect()) may require sending
566 * invalidations for multiple address spaces. We only track one 566 * invalidations for multiple address spaces. We only track one
567 * address space at a time, and if we encounter more than one, then 567 * address space at a time, and if we encounter more than one, then
568 * the notification each CPU gets is to hit the entire TLB. Note 568 * the notification each CPU gets is to hit the entire TLB. Note
569 * also that we can't serialize with pmap_activate() in this case, 569 * also that we can't serialize with pmap_activate() in this case,
570 * so all CPUs will get the notification, and they check when 570 * so all CPUs will get the notification, and they check when
571 * processing the notification if the pmap is current on that CPU. 571 * processing the notification if the pmap is current on that CPU.
572 * 572 *
573 * Invalidation information is gathered into a pmap_tlb_context structure 573 * Invalidation information is gathered into a pmap_tlb_context structure
574 * that includes room for 8 VAs, the pmap the VAs belong to, a bitmap of 574 * that includes room for 8 VAs, the pmap the VAs belong to, a bitmap of
575 * CPUs to be notified, and a list for PT pages that are freed during 575 * CPUs to be notified, and a list for PT pages that are freed during
576 * removal off mappings. The number of valid addresses in the list as 576 * removal off mappings. The number of valid addresses in the list as
577 * well as flags are sqeezed into the lower bits of the first two VAs. 577 * well as flags are sqeezed into the lower bits of the first two VAs.
578 * Storage for this structure is allocated on the stack. We need to be 578 * Storage for this structure is allocated on the stack. We need to be
579 * careful to keep the size of this struture under control. 579 * careful to keep the size of this struture under control.
580 * 580 *
581 * When notifying remote CPUs, we acquire the tlb_lock (which also 581 * When notifying remote CPUs, we acquire the tlb_lock (which also
582 * blocks IPIs), record the pointer to our context structure, set a 582 * blocks IPIs), record the pointer to our context structure, set a
583 * global bitmap off CPUs to be notified, and then send the IPIs to 583 * global bitmap off CPUs to be notified, and then send the IPIs to
584 * each victim. While the other CPUs are in-flight, we then perform 584 * each victim. While the other CPUs are in-flight, we then perform
585 * any invalidations necessary on the local CPU. Once that is done, 585 * any invalidations necessary on the local CPU. Once that is done,
586 * we then wait the the global context pointer to be cleared, which 586 * we then wait the the global context pointer to be cleared, which
587 * will be done by the final remote CPU to complete their work. This 587 * will be done by the final remote CPU to complete their work. This
588 * method reduces cache line contention during pocessing. 588 * method reduces cache line contention during pocessing.
589 * 589 *
590 * When removing mappings in user pmaps, this implemention frees page 590 * When removing mappings in user pmaps, this implemention frees page
591 * table pages back to the VM system once they contain no valid mappings. 591 * table pages back to the VM system once they contain no valid mappings.
592 * As we do this, we must ensure to invalidate TLB entries that the 592 * As we do this, we must ensure to invalidate TLB entries that the
593 * CPU might hold for the respective recursive VPT mappings. This must 593 * CPU might hold for the respective recursive VPT mappings. This must
594 * be done whenever an L1 or L2 PTE is invalidated. Until these VPT 594 * be done whenever an L1 or L2 PTE is invalidated. Until these VPT
595 * translations are invalidated, the PT pages must not be reused. For 595 * translations are invalidated, the PT pages must not be reused. For
596 * this reason, we keep a list of freed PT pages in the context stucture 596 * this reason, we keep a list of freed PT pages in the context stucture
597 * and drain them off once all invalidations are complete. 597 * and drain them off once all invalidations are complete.
598 * 598 *
599 * NOTE: The value of TLB_CTX_MAXVA is tuned to accommodate the UBC 599 * NOTE: The value of TLB_CTX_MAXVA is tuned to accommodate the UBC
600 * window size (defined as 64KB on alpha in <machine/vmparam.h>). 600 * window size (defined as 64KB on alpha in <machine/vmparam.h>).
601 */ 601 */
602 602
603#define TLB_CTX_F_ASM __BIT(0) 603#define TLB_CTX_F_ASM __BIT(0)
604#define TLB_CTX_F_IMB __BIT(1) 604#define TLB_CTX_F_IMB __BIT(1)
605#define TLB_CTX_F_KIMB __BIT(2) 605#define TLB_CTX_F_KIMB __BIT(2)
606#define TLB_CTX_F_PV __BIT(3) 606#define TLB_CTX_F_PV __BIT(3)
607#define TLB_CTX_F_MULTI __BIT(4) 607#define TLB_CTX_F_MULTI __BIT(4)
608 608
609#define TLB_CTX_COUNT(ctx) ((ctx)->t_addrdata[0] & PAGE_MASK) 609#define TLB_CTX_COUNT(ctx) ((ctx)->t_addrdata[0] & PAGE_MASK)
610#define TLB_CTX_INC_COUNT(ctx) (ctx)->t_addrdata[0]++ 610#define TLB_CTX_INC_COUNT(ctx) (ctx)->t_addrdata[0]++
611#define TLB_CTX_SET_ALLVA(ctx) (ctx)->t_addrdata[0] |= TLB_CTX_ALLVA 611#define TLB_CTX_SET_ALLVA(ctx) (ctx)->t_addrdata[0] |= TLB_CTX_ALLVA
612 612
613#define TLB_CTX_FLAGS(ctx) ((ctx)->t_addrdata[1] & PAGE_MASK) 613#define TLB_CTX_FLAGS(ctx) ((ctx)->t_addrdata[1] & PAGE_MASK)
614#define TLB_CTX_SET_FLAG(ctx, f) (ctx)->t_addrdata[1] |= (f) 614#define TLB_CTX_SET_FLAG(ctx, f) (ctx)->t_addrdata[1] |= (f)
615 615
616#define TLB_CTX_VA(ctx, i) ((ctx)->t_addrdata[(i)] & ~PAGE_MASK) 616#define TLB_CTX_VA(ctx, i) ((ctx)->t_addrdata[(i)] & ~PAGE_MASK)
617#define TLB_CTX_SETVA(ctx, i, va) \ 617#define TLB_CTX_SETVA(ctx, i, va) \
618 (ctx)->t_addrdata[(i)] = (va) | ((ctx)->t_addrdata[(i)] & PAGE_MASK) 618 (ctx)->t_addrdata[(i)] = (va) | ((ctx)->t_addrdata[(i)] & PAGE_MASK)
619 619
620static struct { 620static struct {
621 kmutex_t lock; 621 kmutex_t lock;
622 struct evcnt events; 622 struct evcnt events;
623} tlb_shootdown __cacheline_aligned; 623} tlb_shootdown __cacheline_aligned;
624#define tlb_lock tlb_shootdown.lock 624#define tlb_lock tlb_shootdown.lock
625#define tlb_evcnt tlb_shootdown.events 625#define tlb_evcnt tlb_shootdown.events
626#if defined(MULTIPROCESSOR) 626#if defined(MULTIPROCESSOR)
627static const struct pmap_tlb_context *tlb_context __cacheline_aligned; 627static const struct pmap_tlb_context *tlb_context __cacheline_aligned;
628static unsigned long tlb_pending __cacheline_aligned; 628static unsigned long tlb_pending __cacheline_aligned;
629#endif /* MULTIPROCESSOR */ 629#endif /* MULTIPROCESSOR */
630 630
631#if defined(TLB_STATS) 631#if defined(TLB_STATS)
632#define TLB_COUNT_DECL(cnt) static struct evcnt tlb_stat_##cnt 632#define TLB_COUNT_DECL(cnt) static struct evcnt tlb_stat_##cnt
633#define TLB_COUNT(cnt) atomic_inc_64(&tlb_stat_##cnt .ev_count) 633#define TLB_COUNT(cnt) atomic_inc_64(&tlb_stat_##cnt .ev_count)
634#define TLB_COUNT_ATTACH(cnt) \ 634#define TLB_COUNT_ATTACH(cnt) \
635 evcnt_attach_dynamic_nozero(&tlb_stat_##cnt, EVCNT_TYPE_MISC, \ 635 evcnt_attach_dynamic_nozero(&tlb_stat_##cnt, EVCNT_TYPE_MISC, \
636 NULL, "TLB", #cnt) 636 NULL, "TLB", #cnt)
637 637
638TLB_COUNT_DECL(invalidate_multi_tbia); 638TLB_COUNT_DECL(invalidate_multi_tbia);
639TLB_COUNT_DECL(invalidate_multi_tbiap); 639TLB_COUNT_DECL(invalidate_multi_tbiap);
640TLB_COUNT_DECL(invalidate_multi_imb); 640TLB_COUNT_DECL(invalidate_multi_imb);
641 641
642TLB_COUNT_DECL(invalidate_kern_tbia); 642TLB_COUNT_DECL(invalidate_kern_tbia);
643TLB_COUNT_DECL(invalidate_kern_tbis); 643TLB_COUNT_DECL(invalidate_kern_tbis);
644TLB_COUNT_DECL(invalidate_kern_imb); 644TLB_COUNT_DECL(invalidate_kern_imb);
645 645
646TLB_COUNT_DECL(invalidate_user_not_current); 646TLB_COUNT_DECL(invalidate_user_not_current);
647TLB_COUNT_DECL(invalidate_user_lazy_imb); 647TLB_COUNT_DECL(invalidate_user_lazy_imb);
648TLB_COUNT_DECL(invalidate_user_tbiap); 648TLB_COUNT_DECL(invalidate_user_tbiap);
649TLB_COUNT_DECL(invalidate_user_tbis); 649TLB_COUNT_DECL(invalidate_user_tbis);
650 650
651TLB_COUNT_DECL(shootdown_kernel); 651TLB_COUNT_DECL(shootdown_kernel);
652TLB_COUNT_DECL(shootdown_user); 652TLB_COUNT_DECL(shootdown_user);
653TLB_COUNT_DECL(shootdown_imb); 653TLB_COUNT_DECL(shootdown_imb);
654TLB_COUNT_DECL(shootdown_kimb); 654TLB_COUNT_DECL(shootdown_kimb);
655TLB_COUNT_DECL(shootdown_overflow); 655TLB_COUNT_DECL(shootdown_overflow);
656 656
657TLB_COUNT_DECL(shootdown_all_user); 657TLB_COUNT_DECL(shootdown_all_user);
658TLB_COUNT_DECL(shootdown_all_user_imb); 658TLB_COUNT_DECL(shootdown_all_user_imb);
659 659
660TLB_COUNT_DECL(shootdown_pv); 660TLB_COUNT_DECL(shootdown_pv);
661TLB_COUNT_DECL(shootdown_pv_multi); 661TLB_COUNT_DECL(shootdown_pv_multi);
662 662
663TLB_COUNT_DECL(shootnow_over_notify); 663TLB_COUNT_DECL(shootnow_over_notify);
664TLB_COUNT_DECL(shootnow_remote); 664TLB_COUNT_DECL(shootnow_remote);
665 665
666TLB_COUNT_DECL(reason_remove_kernel); 666TLB_COUNT_DECL(reason_remove_kernel);
667TLB_COUNT_DECL(reason_remove_user); 667TLB_COUNT_DECL(reason_remove_user);
668TLB_COUNT_DECL(reason_remove_all_user); 668TLB_COUNT_DECL(reason_remove_all_user);
669TLB_COUNT_DECL(reason_page_protect_read); 669TLB_COUNT_DECL(reason_page_protect_read);
670TLB_COUNT_DECL(reason_page_protect_none); 670TLB_COUNT_DECL(reason_page_protect_none);
671TLB_COUNT_DECL(reason_protect); 671TLB_COUNT_DECL(reason_protect);
672TLB_COUNT_DECL(reason_enter_kernel); 672TLB_COUNT_DECL(reason_enter_kernel);
673TLB_COUNT_DECL(reason_enter_user); 673TLB_COUNT_DECL(reason_enter_user);
674TLB_COUNT_DECL(reason_kenter); 674TLB_COUNT_DECL(reason_kenter);
675TLB_COUNT_DECL(reason_enter_l2pt_delref); 675TLB_COUNT_DECL(reason_enter_l2pt_delref);
676TLB_COUNT_DECL(reason_enter_l3pt_delref); 676TLB_COUNT_DECL(reason_enter_l3pt_delref);
677TLB_COUNT_DECL(reason_kremove); 677TLB_COUNT_DECL(reason_kremove);
678TLB_COUNT_DECL(reason_clear_modify); 678TLB_COUNT_DECL(reason_clear_modify);
679TLB_COUNT_DECL(reason_clear_reference); 679TLB_COUNT_DECL(reason_clear_reference);
680TLB_COUNT_DECL(reason_emulate_reference); 680TLB_COUNT_DECL(reason_emulate_reference);
681 681
682TLB_COUNT_DECL(asn_reuse); 682TLB_COUNT_DECL(asn_reuse);
683TLB_COUNT_DECL(asn_newgen); 683TLB_COUNT_DECL(asn_newgen);
684TLB_COUNT_DECL(asn_assign); 684TLB_COUNT_DECL(asn_assign);
685 685
686TLB_COUNT_DECL(activate_both_change); 686TLB_COUNT_DECL(activate_both_change);
687TLB_COUNT_DECL(activate_asn_change); 687TLB_COUNT_DECL(activate_asn_change);
688TLB_COUNT_DECL(activate_ptbr_change); 688TLB_COUNT_DECL(activate_ptbr_change);
689TLB_COUNT_DECL(activate_swpctx); 689TLB_COUNT_DECL(activate_swpctx);
690TLB_COUNT_DECL(activate_skip_swpctx); 690TLB_COUNT_DECL(activate_skip_swpctx);
691 691
692#else /* ! TLB_STATS */ 692#else /* ! TLB_STATS */
693#define TLB_COUNT(cnt) __nothing 693#define TLB_COUNT(cnt) __nothing
694#define TLB_COUNT_ATTACH(cnt) __nothing 694#define TLB_COUNT_ATTACH(cnt) __nothing
695#endif /* TLB_STATS */ 695#endif /* TLB_STATS */
696 696
697static void 697static void
698pmap_tlb_init(void) 698pmap_tlb_init(void)
699{ 699{
700 /* mutex is initialized in pmap_bootstrap(). */ 700 /* mutex is initialized in pmap_bootstrap(). */
701 701
702 evcnt_attach_dynamic_nozero(&tlb_evcnt, EVCNT_TYPE_MISC, 702 evcnt_attach_dynamic_nozero(&tlb_evcnt, EVCNT_TYPE_MISC,
703 NULL, "TLB", "shootdown"); 703 NULL, "TLB", "shootdown");
704 704
705 TLB_COUNT_ATTACH(invalidate_multi_tbia); 705 TLB_COUNT_ATTACH(invalidate_multi_tbia);
706 TLB_COUNT_ATTACH(invalidate_multi_tbiap); 706 TLB_COUNT_ATTACH(invalidate_multi_tbiap);
707 TLB_COUNT_ATTACH(invalidate_multi_imb); 707 TLB_COUNT_ATTACH(invalidate_multi_imb);
708 708
709 TLB_COUNT_ATTACH(invalidate_kern_tbia); 709 TLB_COUNT_ATTACH(invalidate_kern_tbia);
710 TLB_COUNT_ATTACH(invalidate_kern_tbis); 710 TLB_COUNT_ATTACH(invalidate_kern_tbis);
711 TLB_COUNT_ATTACH(invalidate_kern_imb); 711 TLB_COUNT_ATTACH(invalidate_kern_imb);
712 712
713 TLB_COUNT_ATTACH(invalidate_user_not_current); 713 TLB_COUNT_ATTACH(invalidate_user_not_current);
714 TLB_COUNT_ATTACH(invalidate_user_lazy_imb); 714 TLB_COUNT_ATTACH(invalidate_user_lazy_imb);
715 TLB_COUNT_ATTACH(invalidate_user_tbiap); 715 TLB_COUNT_ATTACH(invalidate_user_tbiap);
716 TLB_COUNT_ATTACH(invalidate_user_tbis); 716 TLB_COUNT_ATTACH(invalidate_user_tbis);
717 717
718 TLB_COUNT_ATTACH(shootdown_kernel); 718 TLB_COUNT_ATTACH(shootdown_kernel);
719 TLB_COUNT_ATTACH(shootdown_user); 719 TLB_COUNT_ATTACH(shootdown_user);
720 TLB_COUNT_ATTACH(shootdown_imb); 720 TLB_COUNT_ATTACH(shootdown_imb);
721 TLB_COUNT_ATTACH(shootdown_kimb); 721 TLB_COUNT_ATTACH(shootdown_kimb);
722 TLB_COUNT_ATTACH(shootdown_overflow); 722 TLB_COUNT_ATTACH(shootdown_overflow);
723 723
724 TLB_COUNT_ATTACH(shootdown_all_user); 724 TLB_COUNT_ATTACH(shootdown_all_user);
725 TLB_COUNT_ATTACH(shootdown_all_user_imb); 725 TLB_COUNT_ATTACH(shootdown_all_user_imb);
726 726
727 TLB_COUNT_ATTACH(shootdown_pv); 727 TLB_COUNT_ATTACH(shootdown_pv);
728 TLB_COUNT_ATTACH(shootdown_pv_multi); 728 TLB_COUNT_ATTACH(shootdown_pv_multi);
729 729
730 TLB_COUNT_ATTACH(shootnow_over_notify); 730 TLB_COUNT_ATTACH(shootnow_over_notify);
731 TLB_COUNT_ATTACH(shootnow_remote); 731 TLB_COUNT_ATTACH(shootnow_remote);
732 732
733 TLB_COUNT_ATTACH(reason_remove_kernel); 733 TLB_COUNT_ATTACH(reason_remove_kernel);
734 TLB_COUNT_ATTACH(reason_remove_user); 734 TLB_COUNT_ATTACH(reason_remove_user);
735 TLB_COUNT_ATTACH(reason_remove_all_user); 735 TLB_COUNT_ATTACH(reason_remove_all_user);
736 TLB_COUNT_ATTACH(reason_page_protect_read); 736 TLB_COUNT_ATTACH(reason_page_protect_read);
737 TLB_COUNT_ATTACH(reason_page_protect_none); 737 TLB_COUNT_ATTACH(reason_page_protect_none);
738 TLB_COUNT_ATTACH(reason_protect); 738 TLB_COUNT_ATTACH(reason_protect);
739 TLB_COUNT_ATTACH(reason_enter_kernel); 739 TLB_COUNT_ATTACH(reason_enter_kernel);
740 TLB_COUNT_ATTACH(reason_enter_user); 740 TLB_COUNT_ATTACH(reason_enter_user);
741 TLB_COUNT_ATTACH(reason_kenter); 741 TLB_COUNT_ATTACH(reason_kenter);
742 TLB_COUNT_ATTACH(reason_enter_l2pt_delref); 742 TLB_COUNT_ATTACH(reason_enter_l2pt_delref);
743 TLB_COUNT_ATTACH(reason_enter_l3pt_delref); 743 TLB_COUNT_ATTACH(reason_enter_l3pt_delref);
744 TLB_COUNT_ATTACH(reason_kremove); 744 TLB_COUNT_ATTACH(reason_kremove);
745 TLB_COUNT_ATTACH(reason_clear_modify); 745 TLB_COUNT_ATTACH(reason_clear_modify);
746 TLB_COUNT_ATTACH(reason_clear_reference); 746 TLB_COUNT_ATTACH(reason_clear_reference);
747 747
748 TLB_COUNT_ATTACH(asn_reuse); 748 TLB_COUNT_ATTACH(asn_reuse);
749 TLB_COUNT_ATTACH(asn_newgen); 749 TLB_COUNT_ATTACH(asn_newgen);
750 TLB_COUNT_ATTACH(asn_assign); 750 TLB_COUNT_ATTACH(asn_assign);
751 751
752 TLB_COUNT_ATTACH(activate_both_change); 752 TLB_COUNT_ATTACH(activate_both_change);
753 TLB_COUNT_ATTACH(activate_asn_change); 753 TLB_COUNT_ATTACH(activate_asn_change);
754 TLB_COUNT_ATTACH(activate_ptbr_change); 754 TLB_COUNT_ATTACH(activate_ptbr_change);
755 TLB_COUNT_ATTACH(activate_swpctx); 755 TLB_COUNT_ATTACH(activate_swpctx);
756 TLB_COUNT_ATTACH(activate_skip_swpctx); 756 TLB_COUNT_ATTACH(activate_skip_swpctx);
757} 757}
758 758
759static inline void 759static inline void
760pmap_tlb_context_init(struct pmap_tlb_context * const tlbctx, uintptr_t flags) 760pmap_tlb_context_init(struct pmap_tlb_context * const tlbctx, uintptr_t flags)
761{ 761{
762 /* Initialize the minimum number of fields. */ 762 /* Initialize the minimum number of fields. */
763 tlbctx->t_addrdata[0] = 0; 763 tlbctx->t_addrdata[0] = 0;
764 tlbctx->t_addrdata[1] = flags; 764 tlbctx->t_addrdata[1] = flags;
765 tlbctx->t_pmap = NULL; 765 tlbctx->t_pmap = NULL;
766 LIST_INIT(&tlbctx->t_freeptq); 766 LIST_INIT(&tlbctx->t_freeptq);
767 LIST_INIT(&tlbctx->t_freepvq); 767 LIST_INIT(&tlbctx->t_freepvq);
768} 768}
769 769
770static void 770static void
771pmap_tlb_shootdown_internal(pmap_t const pmap, vaddr_t const va, 771pmap_tlb_shootdown_internal(pmap_t const pmap, vaddr_t const va,
772 pt_entry_t const pte_bits, struct pmap_tlb_context * const tlbctx) 772 pt_entry_t const pte_bits, struct pmap_tlb_context * const tlbctx)
773{ 773{
774 KASSERT(pmap != NULL); 774 KASSERT(pmap != NULL);
775 KASSERT((va & PAGE_MASK) == 0); 775 KASSERT((va & PAGE_MASK) == 0);
776 776
777 /* 777 /*
778 * Figure out who needs to hear about this, and the scope 778 * Figure out who needs to hear about this, and the scope
779 * of an all-entries invalidate. 779 * of an all-entries invalidate.
780 */ 780 */
781 if (pmap == pmap_kernel()) { 781 if (pmap == pmap_kernel()) {
782 TLB_COUNT(shootdown_kernel); 782 TLB_COUNT(shootdown_kernel);
783 KASSERT(pte_bits & PG_ASM); 783 KASSERT(pte_bits & PG_ASM);
784 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_ASM); 784 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_ASM);
785 785
786 /* Note if an I-stream sync is also needed. */ 786 /* Note if an I-stream sync is also needed. */
787 if (pte_bits & PG_EXEC) { 787 if (pte_bits & PG_EXEC) {
788 TLB_COUNT(shootdown_kimb); 788 TLB_COUNT(shootdown_kimb);
789 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_KIMB); 789 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_KIMB);
790 } 790 }
791 } else { 791 } else {
792 TLB_COUNT(shootdown_user); 792 TLB_COUNT(shootdown_user);
793 KASSERT((pte_bits & PG_ASM) == 0); 793 KASSERT((pte_bits & PG_ASM) == 0);
794 794
795 /* Note if an I-stream sync is also needed. */ 795 /* Note if an I-stream sync is also needed. */
796 if (pte_bits & PG_EXEC) { 796 if (pte_bits & PG_EXEC) {
797 TLB_COUNT(shootdown_imb); 797 TLB_COUNT(shootdown_imb);
798 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_IMB); 798 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_IMB);
799 } 799 }
800 } 800 }
801 801
802 KASSERT(tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap); 802 KASSERT(tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap);
803 tlbctx->t_pmap = pmap; 803 tlbctx->t_pmap = pmap;
804 804
805 /* 805 /*
806 * If we're already at the max, just tell each active CPU 806 * If we're already at the max, just tell each active CPU
807 * to nail everything. 807 * to nail everything.
808 */ 808 */
809 const uintptr_t count = TLB_CTX_COUNT(tlbctx); 809 const uintptr_t count = TLB_CTX_COUNT(tlbctx);
810 if (count > TLB_CTX_MAXVA) { 810 if (count > TLB_CTX_MAXVA) {
811 return; 811 return;
812 } 812 }
813 if (count == TLB_CTX_MAXVA) { 813 if (count == TLB_CTX_MAXVA) {
814 TLB_COUNT(shootdown_overflow); 814 TLB_COUNT(shootdown_overflow);
815 TLB_CTX_SET_ALLVA(tlbctx); 815 TLB_CTX_SET_ALLVA(tlbctx);
816 return; 816 return;
817 } 817 }
818 818
819 TLB_CTX_SETVA(tlbctx, count, va); 819 TLB_CTX_SETVA(tlbctx, count, va);
820 TLB_CTX_INC_COUNT(tlbctx); 820 TLB_CTX_INC_COUNT(tlbctx);
821} 821}
822 822
823static void 823static void
824pmap_tlb_shootdown(pmap_t const pmap, vaddr_t const va, 824pmap_tlb_shootdown(pmap_t const pmap, vaddr_t const va,
825 pt_entry_t const pte_bits, struct pmap_tlb_context * const tlbctx) 825 pt_entry_t const pte_bits, struct pmap_tlb_context * const tlbctx)
826{ 826{
827 KASSERT((TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV) == 0); 827 KASSERT((TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV) == 0);
828 pmap_tlb_shootdown_internal(pmap, va, pte_bits, tlbctx); 828 pmap_tlb_shootdown_internal(pmap, va, pte_bits, tlbctx);
829} 829}
830 830
831static void 831static void
832pmap_tlb_shootdown_all_user(pmap_t const pmap, pt_entry_t const pte_bits, 832pmap_tlb_shootdown_all_user(pmap_t const pmap, pt_entry_t const pte_bits,
833 struct pmap_tlb_context * const tlbctx) 833 struct pmap_tlb_context * const tlbctx)
834{ 834{
835 KASSERT(pmap != pmap_kernel()); 835 KASSERT(pmap != pmap_kernel());
836 836
837 TLB_COUNT(shootdown_all_user); 837 TLB_COUNT(shootdown_all_user);
838 838
839 /* Note if an I-stream sync is also needed. */ 839 /* Note if an I-stream sync is also needed. */
840 if (pte_bits & PG_EXEC) { 840 if (pte_bits & PG_EXEC) {
841 TLB_COUNT(shootdown_all_user_imb); 841 TLB_COUNT(shootdown_all_user_imb);
842 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_IMB); 842 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_IMB);
843 } 843 }
844 844
845 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV) { 845 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV) {
846 if (tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap) { 846 if (tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap) {
847 if (tlbctx->t_pmap == NULL) { 847 if (tlbctx->t_pmap == NULL) {
848 pmap_reference(pmap); 848 pmap_reference(pmap);
849 tlbctx->t_pmap = pmap; 849 tlbctx->t_pmap = pmap;
850 } 850 }
851 } else { 851 } else {
852 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_MULTI); 852 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_MULTI);
853 } 853 }
854 } else { 854 } else {
855 KASSERT(tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap); 855 KASSERT(tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap);
856 tlbctx->t_pmap = pmap; 856 tlbctx->t_pmap = pmap;
857 } 857 }
858 858
859 TLB_CTX_SET_ALLVA(tlbctx); 859 TLB_CTX_SET_ALLVA(tlbctx);
860} 860}
861 861
862static void 862static void
863pmap_tlb_shootdown_pv(pmap_t const pmap, vaddr_t const va, 863pmap_tlb_shootdown_pv(pmap_t const pmap, vaddr_t const va,
864 pt_entry_t const pte_bits, struct pmap_tlb_context * const tlbctx) 864 pt_entry_t const pte_bits, struct pmap_tlb_context * const tlbctx)
865{ 865{
866 866
867 KASSERT(TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV); 867 KASSERT(TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV);
868 868
869 TLB_COUNT(shootdown_pv); 869 TLB_COUNT(shootdown_pv);
870 870
871 if (tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap) { 871 if (tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap) {
872 if (tlbctx->t_pmap == NULL) { 872 if (tlbctx->t_pmap == NULL) {
873 pmap_reference(pmap); 873 pmap_reference(pmap);
874 tlbctx->t_pmap = pmap; 874 tlbctx->t_pmap = pmap;
875 } 875 }
876 pmap_tlb_shootdown_internal(pmap, va, pte_bits, tlbctx); 876 pmap_tlb_shootdown_internal(pmap, va, pte_bits, tlbctx);
877 } else { 877 } else {
878 TLB_COUNT(shootdown_pv_multi); 878 TLB_COUNT(shootdown_pv_multi);
879 uintptr_t flags = TLB_CTX_F_MULTI; 879 uintptr_t flags = TLB_CTX_F_MULTI;
880 if (pmap == pmap_kernel()) { 880 if (pmap == pmap_kernel()) {
881 KASSERT(pte_bits & PG_ASM); 881 KASSERT(pte_bits & PG_ASM);
882 flags |= TLB_CTX_F_ASM; 882 flags |= TLB_CTX_F_ASM;
883 } else { 883 } else {
884 KASSERT((pte_bits & PG_ASM) == 0); 884 KASSERT((pte_bits & PG_ASM) == 0);
885 } 885 }
886 886
887 /* 887 /*
888 * No need to distinguish between kernel and user IMB 888 * No need to distinguish between kernel and user IMB
889 * here; see pmap_tlb_invalidate_multi(). 889 * here; see pmap_tlb_invalidate_multi().
890 */ 890 */
891 if (pte_bits & PG_EXEC) { 891 if (pte_bits & PG_EXEC) {
892 flags |= TLB_CTX_F_IMB; 892 flags |= TLB_CTX_F_IMB;
893 } 893 }
894 TLB_CTX_SET_ALLVA(tlbctx); 894 TLB_CTX_SET_ALLVA(tlbctx);
895 TLB_CTX_SET_FLAG(tlbctx, flags); 895 TLB_CTX_SET_FLAG(tlbctx, flags);
896 } 896 }
897} 897}
898 898
899static void 899static void
900pmap_tlb_invalidate_multi(const struct pmap_tlb_context * const tlbctx) 900pmap_tlb_invalidate_multi(const struct pmap_tlb_context * const tlbctx)
901{ 901{
902 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_ASM) { 902 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_ASM) {
903 TLB_COUNT(invalidate_multi_tbia); 903 TLB_COUNT(invalidate_multi_tbia);
904 ALPHA_TBIA(); 904 ALPHA_TBIA();
905 } else { 905 } else {
906 TLB_COUNT(invalidate_multi_tbiap); 906 TLB_COUNT(invalidate_multi_tbiap);
907 ALPHA_TBIAP(); 907 ALPHA_TBIAP();
908 } 908 }
909 if (TLB_CTX_FLAGS(tlbctx) & (TLB_CTX_F_IMB | TLB_CTX_F_KIMB)) { 909 if (TLB_CTX_FLAGS(tlbctx) & (TLB_CTX_F_IMB | TLB_CTX_F_KIMB)) {
910 TLB_COUNT(invalidate_multi_imb); 910 TLB_COUNT(invalidate_multi_imb);
911 alpha_pal_imb(); 911 alpha_pal_imb();
912 } 912 }
913} 913}
914 914
915static void 915static void
916pmap_tlb_invalidate_kernel(const struct pmap_tlb_context * const tlbctx) 916pmap_tlb_invalidate_kernel(const struct pmap_tlb_context * const tlbctx)
917{ 917{
918 const uintptr_t count = TLB_CTX_COUNT(tlbctx); 918 const uintptr_t count = TLB_CTX_COUNT(tlbctx);
919 919
920 if (count == TLB_CTX_ALLVA) { 920 if (count == TLB_CTX_ALLVA) {
921 TLB_COUNT(invalidate_kern_tbia); 921 TLB_COUNT(invalidate_kern_tbia);
922 ALPHA_TBIA(); 922 ALPHA_TBIA();
923 } else { 923 } else {
924 TLB_COUNT(invalidate_kern_tbis); 924 TLB_COUNT(invalidate_kern_tbis);
925 for (uintptr_t i = 0; i < count; i++) { 925 for (uintptr_t i = 0; i < count; i++) {
926 ALPHA_TBIS(TLB_CTX_VA(tlbctx, i)); 926 ALPHA_TBIS(TLB_CTX_VA(tlbctx, i));
927 } 927 }
928 } 928 }
929 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_KIMB) { 929 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_KIMB) {
930 TLB_COUNT(invalidate_kern_imb); 930 TLB_COUNT(invalidate_kern_imb);
931 alpha_pal_imb(); 931 alpha_pal_imb();
932 } 932 }
933} 933}
934 934
935static void 935static void
936pmap_tlb_invalidate(const struct pmap_tlb_context * const tlbctx, 936pmap_tlb_invalidate(const struct pmap_tlb_context * const tlbctx,
937 const struct cpu_info * const ci) 937 const struct cpu_info * const ci)
938{ 938{
939 const uintptr_t count = TLB_CTX_COUNT(tlbctx); 939 const uintptr_t count = TLB_CTX_COUNT(tlbctx);
940 940
941 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_MULTI) { 941 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_MULTI) {
942 pmap_tlb_invalidate_multi(tlbctx); 942 pmap_tlb_invalidate_multi(tlbctx);
943 return; 943 return;
944 } 944 }
945 945
946 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_ASM) { 946 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_ASM) {
947 pmap_tlb_invalidate_kernel(tlbctx); 947 pmap_tlb_invalidate_kernel(tlbctx);
948 return; 948 return;
949 } 949 }
950 950
951 KASSERT(kpreempt_disabled()); 951 KASSERT(kpreempt_disabled());
952 952
953 pmap_t const pmap = tlbctx->t_pmap; 953 pmap_t const pmap = tlbctx->t_pmap;
954 KASSERT(pmap != NULL); 954 KASSERT(pmap != NULL);
955 955
956 if (__predict_false(pmap != ci->ci_pmap)) { 956 if (__predict_false(pmap != ci->ci_pmap)) {
957 TLB_COUNT(invalidate_user_not_current); 957 TLB_COUNT(invalidate_user_not_current);
958 958
959 /* 959 /*
960 * For CPUs that don't implement ASNs, the SWPCTX call 960 * For CPUs that don't implement ASNs, the SWPCTX call
961 * does all of the TLB invalidation work for us. 961 * does all of the TLB invalidation work for us.
962 */ 962 */
963 if (__predict_false(pmap_max_asn == 0)) { 963 if (__predict_false(pmap_max_asn == 0)) {
964 return; 964 return;
965 } 965 }
966 966
967 const u_long cpu_mask = 1UL << ci->ci_cpuid; 967 const u_long cpu_mask = 1UL << ci->ci_cpuid;
968 968
969 /* 969 /*
970 * We cannot directly invalidate the TLB in this case, 970 * We cannot directly invalidate the TLB in this case,
971 * so force allocation of a new ASN when the pmap becomes 971 * so force allocation of a new ASN when the pmap becomes
972 * active again. 972 * active again.
973 */ 973 */
974 pmap->pm_percpu[ci->ci_cpuid].pmc_asngen = PMAP_ASNGEN_INVALID; 974 pmap->pm_percpu[ci->ci_cpuid].pmc_asngen = PMAP_ASNGEN_INVALID;
975 atomic_and_ulong(&pmap->pm_cpus, ~cpu_mask); 975 atomic_and_ulong(&pmap->pm_cpus, ~cpu_mask);
976 976
977 /* 977 /*
978 * This isn't strictly necessary; when we allocate a 978 * This isn't strictly necessary; when we allocate a
979 * new ASN, we're going to clear this bit and skip 979 * new ASN, we're going to clear this bit and skip
980 * syncing the I-stream. But we will keep this bit 980 * syncing the I-stream. But we will keep this bit
981 * of accounting for internal consistency. 981 * of accounting for internal consistency.
982 */ 982 */
983 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_IMB) { 983 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_IMB) {
984 pmap->pm_percpu[ci->ci_cpuid].pmc_needisync = 1; 984 pmap->pm_percpu[ci->ci_cpuid].pmc_needisync = 1;
985 } 985 }
986 return; 986 return;
987 } 987 }
988 988
989 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_IMB) { 989 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_IMB) {
990 TLB_COUNT(invalidate_user_lazy_imb); 990 TLB_COUNT(invalidate_user_lazy_imb);
991 pmap->pm_percpu[ci->ci_cpuid].pmc_needisync = 1; 991 pmap->pm_percpu[ci->ci_cpuid].pmc_needisync = 1;
992 } 992 }
993 993
994 if (count == TLB_CTX_ALLVA) { 994 if (count == TLB_CTX_ALLVA) {
995 /* 995 /*
996 * Another option here for CPUs that implement ASNs is 996 * Another option here for CPUs that implement ASNs is
997 * to allocate a new ASN and do a SWPCTX. That's almost 997 * to allocate a new ASN and do a SWPCTX. That's almost
998 * certainly faster than a TBIAP, but would require us 998 * certainly faster than a TBIAP, but would require us
999 * to synchronize against IPIs in pmap_activate(). 999 * to synchronize against IPIs in pmap_activate().
1000 */ 1000 */
1001 TLB_COUNT(invalidate_user_tbiap); 1001 TLB_COUNT(invalidate_user_tbiap);
1002 KASSERT((TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_ASM) == 0); 1002 KASSERT((TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_ASM) == 0);
1003 ALPHA_TBIAP(); 1003 ALPHA_TBIAP();
1004 } else { 1004 } else {
1005 TLB_COUNT(invalidate_user_tbis); 1005 TLB_COUNT(invalidate_user_tbis);
1006 for (uintptr_t i = 0; i < count; i++) { 1006 for (uintptr_t i = 0; i < count; i++) {
1007 ALPHA_TBIS(TLB_CTX_VA(tlbctx, i)); 1007 ALPHA_TBIS(TLB_CTX_VA(tlbctx, i));
1008 } 1008 }
1009 } 1009 }
1010} 1010}
1011 1011
1012static void 1012static void
1013pmap_tlb_shootnow(const struct pmap_tlb_context * const tlbctx) 1013pmap_tlb_shootnow(const struct pmap_tlb_context * const tlbctx)
1014{ 1014{
1015 1015
1016 if (TLB_CTX_COUNT(tlbctx) == 0) { 1016 if (TLB_CTX_COUNT(tlbctx) == 0) {
1017 /* No work to do. */ 1017 /* No work to do. */
1018 return; 1018 return;
1019 } 1019 }
1020 1020
1021 /* 1021 /*
1022 * Acquire the shootdown mutex. This will also block IPL_VM 1022 * Acquire the shootdown mutex. This will also block IPL_VM
1023 * interrupts and disable preemption. It is critically important 1023 * interrupts and disable preemption. It is critically important
1024 * that IPIs not be blocked in this routine. 1024 * that IPIs not be blocked in this routine.
1025 */ 1025 */
1026 KASSERT((alpha_pal_rdps() & ALPHA_PSL_IPL_MASK) < ALPHA_PSL_IPL_CLOCK); 1026 KASSERT((alpha_pal_rdps() & ALPHA_PSL_IPL_MASK) < ALPHA_PSL_IPL_CLOCK);
1027 mutex_spin_enter(&tlb_lock); 1027 mutex_spin_enter(&tlb_lock);
1028 tlb_evcnt.ev_count++; 1028 tlb_evcnt.ev_count++;
1029 1029
1030 const struct cpu_info *ci = curcpu(); 1030 const struct cpu_info *ci = curcpu();
1031 const u_long this_cpu = 1UL << ci->ci_cpuid; 1031 const u_long this_cpu = 1UL << ci->ci_cpuid;
1032 u_long active_cpus; 1032 u_long active_cpus;
1033 bool activation_locked, activation_lock_tried; 1033 bool activation_locked, activation_lock_tried;
1034 1034
1035 /* 1035 /*
1036 * Figure out who to notify. If it's for the kernel or 1036 * Figure out who to notify. If it's for the kernel or
1037 * multiple aaddress spaces, we notify everybody. If 1037 * multiple aaddress spaces, we notify everybody. If
1038 * it's a single user pmap, then we try to acquire the 1038 * it's a single user pmap, then we try to acquire the
1039 * activation lock so we can get an accurate accounting 1039 * activation lock so we can get an accurate accounting
1040 * of who needs to be notified. If we can't acquire 1040 * of who needs to be notified. If we can't acquire
1041 * the activation lock, then just notify everyone and 1041 * the activation lock, then just notify everyone and
1042 * let them sort it out when they process the IPI. 1042 * let them sort it out when they process the IPI.
1043 */ 1043 */
1044 if (TLB_CTX_FLAGS(tlbctx) & (TLB_CTX_F_ASM | TLB_CTX_F_MULTI)) { 1044 if (TLB_CTX_FLAGS(tlbctx) & (TLB_CTX_F_ASM | TLB_CTX_F_MULTI)) {
1045 active_cpus = pmap_all_cpus(); 1045 active_cpus = pmap_all_cpus();
1046 activation_locked = false; 1046 activation_locked = false;
1047 activation_lock_tried = false; 1047 activation_lock_tried = false;
1048 } else { 1048 } else {
1049 KASSERT(tlbctx->t_pmap != NULL); 1049 KASSERT(tlbctx->t_pmap != NULL);
1050 activation_locked = PMAP_ACT_TRYLOCK(tlbctx->t_pmap); 1050 activation_locked = PMAP_ACT_TRYLOCK(tlbctx->t_pmap);
1051 if (__predict_true(activation_locked)) { 1051 if (__predict_true(activation_locked)) {
1052 active_cpus = tlbctx->t_pmap->pm_cpus; 1052 active_cpus = tlbctx->t_pmap->pm_cpus;
1053 } else { 1053 } else {
1054 TLB_COUNT(shootnow_over_notify); 1054 TLB_COUNT(shootnow_over_notify);
1055 active_cpus = pmap_all_cpus(); 1055 active_cpus = pmap_all_cpus();
1056 } 1056 }
1057 activation_lock_tried = true; 1057 activation_lock_tried = true;
1058 } 1058 }
1059 1059
1060#if defined(MULTIPROCESSOR) 1060#if defined(MULTIPROCESSOR)
1061 /* 1061 /*
1062 * If there are remote CPUs that need to do work, get them 1062 * If there are remote CPUs that need to do work, get them
1063 * started now. 1063 * started now.
1064 */ 1064 */
1065 const u_long remote_cpus = active_cpus & ~this_cpu; 1065 const u_long remote_cpus = active_cpus & ~this_cpu;
1066 KASSERT(tlb_context == NULL); 1066 KASSERT(tlb_context == NULL);
1067 if (remote_cpus) { 1067 if (remote_cpus) {
1068 TLB_COUNT(shootnow_remote); 1068 TLB_COUNT(shootnow_remote);
1069 tlb_context = tlbctx; 1069 tlb_context = tlbctx;
1070 tlb_pending = remote_cpus; 1070 tlb_pending = remote_cpus;
1071 alpha_multicast_ipi(remote_cpus, ALPHA_IPI_SHOOTDOWN); 1071 alpha_multicast_ipi(remote_cpus, ALPHA_IPI_SHOOTDOWN);
1072 } 1072 }
1073#endif /* MULTIPROCESSOR */ 1073#endif /* MULTIPROCESSOR */
1074 1074
1075 /* 1075 /*
1076 * Now that the remotes have been notified, release the 1076 * Now that the remotes have been notified, release the
1077 * activation lock. 1077 * activation lock.
1078 */ 1078 */
1079 if (activation_lock_tried) { 1079 if (activation_lock_tried) {
1080 if (activation_locked) { 1080 if (activation_locked) {
1081 KASSERT(tlbctx->t_pmap != NULL); 1081 KASSERT(tlbctx->t_pmap != NULL);
1082 PMAP_ACT_UNLOCK(tlbctx->t_pmap); 1082 PMAP_ACT_UNLOCK(tlbctx->t_pmap);
1083 } 1083 }
1084 /* 1084 /*
1085 * When we tried to acquire the activation lock, we 1085 * When we tried to acquire the activation lock, we
1086 * raised IPL to IPL_SCHED (even if we ultimately 1086 * raised IPL to IPL_SCHED (even if we ultimately
1087 * failed to acquire the lock), which blocks out IPIs. 1087 * failed to acquire the lock), which blocks out IPIs.
1088 * Force our IPL back down to IPL_VM so that we can 1088 * Force our IPL back down to IPL_VM so that we can
1089 * receive IPIs. 1089 * receive IPIs.
1090 */ 1090 */
1091 alpha_pal_swpipl(IPL_VM); 1091 alpha_pal_swpipl(IPL_VM);
1092 } 1092 }
1093 1093
1094 /* 1094 /*
1095 * Do any work that we might need to do. We don't need to 1095 * Do any work that we might need to do. We don't need to
1096 * synchronize with activation here because we know that 1096 * synchronize with activation here because we know that
1097 * for the current CPU, activation status will not change. 1097 * for the current CPU, activation status will not change.
1098 */ 1098 */
1099 if (active_cpus & this_cpu) { 1099 if (active_cpus & this_cpu) {
1100 pmap_tlb_invalidate(tlbctx, ci); 1100 pmap_tlb_invalidate(tlbctx, ci);
1101 } 1101 }
1102 1102
1103#if defined(MULTIPROCESSOR) 1103#if defined(MULTIPROCESSOR)
1104 /* Wait for remote CPUs to finish. */ 1104 /* Wait for remote CPUs to finish. */
1105 if (remote_cpus) { 1105 if (remote_cpus) {
1106 int backoff = SPINLOCK_BACKOFF_MIN; 1106 int backoff = SPINLOCK_BACKOFF_MIN;
1107 u_int spins = 0; 1107 u_int spins = 0;
1108 1108
1109 while (atomic_load_acquire(&tlb_context) != NULL) { 1109 while (atomic_load_acquire(&tlb_context) != NULL) {
1110 SPINLOCK_BACKOFF(backoff); 1110 SPINLOCK_BACKOFF(backoff);
1111 if (spins++ > 0x0fffffff) { 1111 if (spins++ > 0x0fffffff) {
1112 printf("TLB LOCAL MASK = 0x%016lx\n", 1112 printf("TLB LOCAL MASK = 0x%016lx\n",
1113 this_cpu); 1113 this_cpu);
1114 printf("TLB REMOTE MASK = 0x%016lx\n", 1114 printf("TLB REMOTE MASK = 0x%016lx\n",
1115 remote_cpus); 1115 remote_cpus);
1116 printf("TLB REMOTE PENDING = 0x%016lx\n", 1116 printf("TLB REMOTE PENDING = 0x%016lx\n",
1117 tlb_pending); 1117 tlb_pending);
1118 printf("TLB CONTEXT = %p\n", tlb_context); 1118 printf("TLB CONTEXT = %p\n", tlb_context);
1119 printf("TLB LOCAL IPL = %lu\n", 1119 printf("TLB LOCAL IPL = %lu\n",
1120 alpha_pal_rdps() & ALPHA_PSL_IPL_MASK); 1120 alpha_pal_rdps() & ALPHA_PSL_IPL_MASK);
1121 panic("pmap_tlb_shootnow"); 1121 panic("pmap_tlb_shootnow");
1122 } 1122 }
1123 } 1123 }
1124 } 1124 }
1125 KASSERT(tlb_context == NULL); 1125 KASSERT(tlb_context == NULL);
1126#endif /* MULTIPROCESSOR */ 1126#endif /* MULTIPROCESSOR */
1127 1127
1128 mutex_spin_exit(&tlb_lock); 1128 mutex_spin_exit(&tlb_lock);
1129 1129
1130 if (__predict_false(TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV)) { 1130 if (__predict_false(TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV)) {
1131 /* 1131 /*
1132 * P->V TLB operations may operate on multiple pmaps. 1132 * P->V TLB operations may operate on multiple pmaps.
1133 * The shootdown takes a reference on the first pmap it 1133 * The shootdown takes a reference on the first pmap it
1134 * encounters, in order to prevent it from disappearing, 1134 * encounters, in order to prevent it from disappearing,
1135 * in the hope that we end up with a single-pmap P->V 1135 * in the hope that we end up with a single-pmap P->V
1136 * operation (instrumentation shows this is not rare). 1136 * operation (instrumentation shows this is not rare).
1137 * 1137 *
1138 * Once this shootdown is finished globally, we need to 1138 * Once this shootdown is finished globally, we need to
1139 * release this extra reference. 1139 * release this extra reference.
1140 */ 1140 */
1141 KASSERT(tlbctx->t_pmap != NULL); 1141 KASSERT(tlbctx->t_pmap != NULL);
1142 pmap_destroy(tlbctx->t_pmap); 1142 pmap_destroy(tlbctx->t_pmap);
1143 } 1143 }
1144} 1144}
1145 1145
1146#if defined(MULTIPROCESSOR) 1146#if defined(MULTIPROCESSOR)
1147void 1147void
1148pmap_tlb_shootdown_ipi(struct cpu_info * const ci, 1148pmap_tlb_shootdown_ipi(struct cpu_info * const ci,
1149 1149
1150 struct trapframe * const tf __unused) 1150 struct trapframe * const tf __unused)
1151{ 1151{
1152 KASSERT(tlb_context != NULL); 1152 KASSERT(tlb_context != NULL);
1153 pmap_tlb_invalidate(tlb_context, ci); 1153 pmap_tlb_invalidate(tlb_context, ci);
1154 if (atomic_and_ulong_nv(&tlb_pending, ~(1UL << ci->ci_cpuid)) == 0) { 1154 if (atomic_and_ulong_nv(&tlb_pending, ~(1UL << ci->ci_cpuid)) == 0) {
1155 atomic_store_release(&tlb_context, NULL); 1155 atomic_store_release(&tlb_context, NULL);
1156 } 1156 }
1157} 1157}
1158#endif /* MULTIPROCESSOR */ 1158#endif /* MULTIPROCESSOR */
1159 1159
1160static inline void 1160static inline void
1161pmap_tlb_context_drain(struct pmap_tlb_context * const tlbctx) 1161pmap_tlb_context_drain(struct pmap_tlb_context * const tlbctx)
1162{ 1162{
1163 if (! LIST_EMPTY(&tlbctx->t_freeptq)) { 1163 if (! LIST_EMPTY(&tlbctx->t_freeptq)) {
1164 pmap_pagelist_free(&tlbctx->t_freeptq); 1164 pmap_pagelist_free(&tlbctx->t_freeptq);
1165 } 1165 }
1166 if (! LIST_EMPTY(&tlbctx->t_freepvq)) { 1166 if (! LIST_EMPTY(&tlbctx->t_freepvq)) {
1167 pmap_pvlist_free(&tlbctx->t_freepvq); 1167 pmap_pvlist_free(&tlbctx->t_freepvq);
1168 } 1168 }
1169} 1169}
1170 1170
1171/* 1171/*
1172 * ASN management functions. 1172 * ASN management functions.
1173 */ 1173 */
1174static u_int pmap_asn_alloc(pmap_t, struct cpu_info *); 1174static u_int pmap_asn_alloc(pmap_t, struct cpu_info *);
1175 1175
1176/* 1176/*
1177 * Misc. functions. 1177 * Misc. functions.
1178 */ 1178 */
1179static struct vm_page *pmap_physpage_alloc(int); 1179static struct vm_page *pmap_physpage_alloc(int);
1180static void pmap_physpage_free(paddr_t); 1180static void pmap_physpage_free(paddr_t);
1181static int pmap_physpage_addref(void *); 1181static int pmap_physpage_addref(void *);
1182static int pmap_physpage_delref(void *); 1182static int pmap_physpage_delref(void *);
1183 1183
1184static bool vtophys_internal(vaddr_t, paddr_t *p); 1184static bool vtophys_internal(vaddr_t, paddr_t *p);
1185 1185
1186/* 1186/*
1187 * PMAP_KERNEL_PTE: 1187 * PMAP_KERNEL_PTE:
1188 * 1188 *
1189 * Get a kernel PTE. 1189 * Get a kernel PTE.
1190 * 1190 *
1191 * If debugging, do a table walk. If not debugging, just use 1191 * If debugging, do a table walk. If not debugging, just use
1192 * the Virtual Page Table, since all kernel page tables are 1192 * the Virtual Page Table, since all kernel page tables are
1193 * pre-allocated and mapped in. 1193 * pre-allocated and mapped in.
1194 */ 1194 */
1195#ifdef DEBUG 1195#ifdef DEBUG
1196#define PMAP_KERNEL_PTE(va) \ 1196#define PMAP_KERNEL_PTE(va) \
1197({ \ 1197({ \
1198 pt_entry_t *l1pte_, *l2pte_; \ 1198 pt_entry_t *l1pte_, *l2pte_; \
1199 \ 1199 \
1200 l1pte_ = pmap_l1pte(kernel_lev1map, va); \ 1200 l1pte_ = pmap_l1pte(kernel_lev1map, va); \
1201 if (pmap_pte_v(l1pte_) == 0) { \ 1201 if (pmap_pte_v(l1pte_) == 0) { \
1202 printf("kernel level 1 PTE not valid, va 0x%lx " \ 1202 printf("kernel level 1 PTE not valid, va 0x%lx " \
1203 "(line %d)\n", (va), __LINE__); \ 1203 "(line %d)\n", (va), __LINE__); \
1204 panic("PMAP_KERNEL_PTE"); \ 1204 panic("PMAP_KERNEL_PTE"); \
1205 } \ 1205 } \
1206 l2pte_ = pmap_l2pte(kernel_lev1map, va, l1pte_); \ 1206 l2pte_ = pmap_l2pte(kernel_lev1map, va, l1pte_); \
1207 if (pmap_pte_v(l2pte_) == 0) { \ 1207 if (pmap_pte_v(l2pte_) == 0) { \
1208 printf("kernel level 2 PTE not valid, va 0x%lx " \ 1208 printf("kernel level 2 PTE not valid, va 0x%lx " \
1209 "(line %d)\n", (va), __LINE__); \ 1209 "(line %d)\n", (va), __LINE__); \
1210 panic("PMAP_KERNEL_PTE"); \ 1210 panic("PMAP_KERNEL_PTE"); \
1211 } \ 1211 } \
1212 pmap_l3pte(kernel_lev1map, va, l2pte_); \ 1212 pmap_l3pte(kernel_lev1map, va, l2pte_); \
1213}) 1213})
1214#else 1214#else
1215#define PMAP_KERNEL_PTE(va) (&VPT[VPT_INDEX((va))]) 1215#define PMAP_KERNEL_PTE(va) (&VPT[VPT_INDEX((va))])
1216#endif 1216#endif
1217 1217
1218/* 1218/*
1219 * PMAP_STAT_{INCR,DECR}: 1219 * PMAP_STAT_{INCR,DECR}:
1220 * 1220 *
1221 * Increment or decrement a pmap statistic. 1221 * Increment or decrement a pmap statistic.
1222 */ 1222 */
1223#define PMAP_STAT_INCR(s, v) atomic_add_long((unsigned long *)(&(s)), (v)) 1223#define PMAP_STAT_INCR(s, v) atomic_add_long((unsigned long *)(&(s)), (v))
1224#define PMAP_STAT_DECR(s, v) atomic_add_long((unsigned long *)(&(s)), -(v)) 1224#define PMAP_STAT_DECR(s, v) atomic_add_long((unsigned long *)(&(s)), -(v))
1225 1225
1226/* 1226/*
1227 * pmap_init_cpu: 1227 * pmap_init_cpu:
1228 * 1228 *
1229 * Initilize pmap data in the cpu_info. 1229 * Initilize pmap data in the cpu_info.
1230 */ 1230 */
1231void 1231void
1232pmap_init_cpu(struct cpu_info * const ci) 1232pmap_init_cpu(struct cpu_info * const ci)
1233{ 1233{
1234 pmap_t const pmap = pmap_kernel(); 1234 pmap_t const pmap = pmap_kernel();
1235 1235
1236 /* All CPUs start out using the kernel pmap. */ 1236 /* All CPUs start out using the kernel pmap. */
1237 atomic_or_ulong(&pmap->pm_cpus, 1UL << ci->ci_cpuid); 1237 atomic_or_ulong(&pmap->pm_cpus, 1UL << ci->ci_cpuid);
1238 pmap_reference(pmap); 1238 pmap_reference(pmap);
1239 ci->ci_pmap = pmap; 1239 ci->ci_pmap = pmap;
1240 1240
1241 /* Initialize ASN allocation logic. */ 1241 /* Initialize ASN allocation logic. */
1242 ci->ci_next_asn = PMAP_ASN_FIRST_USER; 1242 ci->ci_next_asn = PMAP_ASN_FIRST_USER;
1243 ci->ci_asn_gen = PMAP_ASNGEN_INITIAL; 1243 ci->ci_asn_gen = PMAP_ASNGEN_INITIAL;
1244} 1244}
1245 1245
1246/* 1246/*
1247 * pmap_bootstrap: 1247 * pmap_bootstrap:
1248 * 1248 *
1249 * Bootstrap the system to run with virtual memory. 1249 * Bootstrap the system to run with virtual memory.
1250 * 1250 *
1251 * Note: no locking is necessary in this function. 1251 * Note: no locking is necessary in this function.
1252 */ 1252 */
1253void 1253void
1254pmap_bootstrap(paddr_t ptaddr, u_int maxasn, u_long ncpuids) 1254pmap_bootstrap(paddr_t ptaddr, u_int maxasn, u_long ncpuids)
1255{ 1255{
1256 vsize_t lev2mapsize, lev3mapsize; 1256 vsize_t lev2mapsize, lev3mapsize;
1257 pt_entry_t *lev2map, *lev3map; 1257 pt_entry_t *lev2map, *lev3map;
1258 pt_entry_t pte; 1258 pt_entry_t pte;
1259 vsize_t bufsz; 1259 vsize_t bufsz;
1260 struct pcb *pcb; 1260 struct pcb *pcb;
1261 int i; 1261 int i;
1262 1262
1263#ifdef DEBUG 1263#ifdef DEBUG
1264 if (pmapdebug & (PDB_FOLLOW|PDB_BOOTSTRAP)) 1264 if (pmapdebug & (PDB_FOLLOW|PDB_BOOTSTRAP))
1265 printf("pmap_bootstrap(0x%lx, %u)\n", ptaddr, maxasn); 1265 printf("pmap_bootstrap(0x%lx, %u)\n", ptaddr, maxasn);
1266#endif 1266#endif
1267 1267
1268 /* 1268 /*
1269 * Compute the number of pages kmem_arena will have. 1269 * Compute the number of pages kmem_arena will have.
1270 */ 1270 */
1271 kmeminit_nkmempages(); 1271 kmeminit_nkmempages();
1272 1272
1273 /* 1273 /*
1274 * Figure out how many initial PTE's are necessary to map the 1274 * Figure out how many initial PTE's are necessary to map the
1275 * kernel. We also reserve space for kmem_alloc_pageable() 1275 * kernel. We also reserve space for kmem_alloc_pageable()
1276 * for vm_fork(). 1276 * for vm_fork().
1277 */ 1277 */
1278 1278
1279 /* Get size of buffer cache and set an upper limit */ 1279 /* Get size of buffer cache and set an upper limit */
1280 bufsz = buf_memcalc(); 1280 bufsz = buf_memcalc();
1281 buf_setvalimit(bufsz); 1281 buf_setvalimit(bufsz);
1282 1282
1283 lev3mapsize = 1283 lev3mapsize =
1284 (VM_PHYS_SIZE + (ubc_nwins << ubc_winshift) + 1284 (VM_PHYS_SIZE + (ubc_nwins << ubc_winshift) +
1285 bufsz + 16 * NCARGS + pager_map_size) / PAGE_SIZE + 1285 bufsz + 16 * NCARGS + pager_map_size) / PAGE_SIZE +
1286 (maxproc * UPAGES) + nkmempages; 1286 (maxproc * UPAGES) + nkmempages;
1287 1287
1288 lev3mapsize = roundup(lev3mapsize, NPTEPG); 1288 lev3mapsize = roundup(lev3mapsize, NPTEPG);
1289 1289
1290 /* 1290 /*
1291 * Initialize `FYI' variables. Note we're relying on 1291 * Initialize `FYI' variables. Note we're relying on
1292 * the fact that BSEARCH sorts the vm_physmem[] array 1292 * the fact that BSEARCH sorts the vm_physmem[] array
1293 * for us. 1293 * for us.
1294 */ 1294 */
1295 avail_start = ptoa(uvm_physseg_get_avail_start(uvm_physseg_get_first())); 1295 avail_start = ptoa(uvm_physseg_get_avail_start(uvm_physseg_get_first()));
1296 avail_end = ptoa(uvm_physseg_get_avail_end(uvm_physseg_get_last())); 1296 avail_end = ptoa(uvm_physseg_get_avail_end(uvm_physseg_get_last()));
1297 virtual_end = VM_MIN_KERNEL_ADDRESS + lev3mapsize * PAGE_SIZE; 1297 virtual_end = VM_MIN_KERNEL_ADDRESS + lev3mapsize * PAGE_SIZE;
1298 1298
1299#if 0 1299#if 0
1300 printf("avail_start = 0x%lx\n", avail_start); 1300 printf("avail_start = 0x%lx\n", avail_start);
1301 printf("avail_end = 0x%lx\n", avail_end); 1301 printf("avail_end = 0x%lx\n", avail_end);
1302 printf("virtual_end = 0x%lx\n", virtual_end); 1302 printf("virtual_end = 0x%lx\n", virtual_end);
1303#endif 1303#endif
1304 1304
1305 /* 1305 /*
1306 * Allocate a level 1 PTE table for the kernel. 1306 * Allocate a level 1 PTE table for the kernel.
1307 * This is always one page long. 1307 * This is always one page long.
1308 * IF THIS IS NOT A MULTIPLE OF PAGE_SIZE, ALL WILL GO TO HELL. 1308 * IF THIS IS NOT A MULTIPLE OF PAGE_SIZE, ALL WILL GO TO HELL.
1309 */ 1309 */
1310 kernel_lev1map = (pt_entry_t *) 1310 kernel_lev1map = (pt_entry_t *)
1311 uvm_pageboot_alloc(sizeof(pt_entry_t) * NPTEPG); 1311 uvm_pageboot_alloc(sizeof(pt_entry_t) * NPTEPG);
1312 1312
1313 /* 1313 /*
1314 * Allocate a level 2 PTE table for the kernel. 1314 * Allocate a level 2 PTE table for the kernel.
1315 * These must map all of the level3 PTEs. 1315 * These must map all of the level3 PTEs.
1316 * IF THIS IS NOT A MULTIPLE OF PAGE_SIZE, ALL WILL GO TO HELL. 1316 * IF THIS IS NOT A MULTIPLE OF PAGE_SIZE, ALL WILL GO TO HELL.
1317 */ 1317 */
1318 lev2mapsize = roundup(howmany(lev3mapsize, NPTEPG), NPTEPG); 1318 lev2mapsize = roundup(howmany(lev3mapsize, NPTEPG), NPTEPG);
1319 lev2map = (pt_entry_t *) 1319 lev2map = (pt_entry_t *)
1320 uvm_pageboot_alloc(sizeof(pt_entry_t) * lev2mapsize); 1320 uvm_pageboot_alloc(sizeof(pt_entry_t) * lev2mapsize);
1321 1321
1322 /* 1322 /*
1323 * Allocate a level 3 PTE table for the kernel. 1323 * Allocate a level 3 PTE table for the kernel.
1324 * Contains lev3mapsize PTEs. 1324 * Contains lev3mapsize PTEs.
1325 */ 1325 */
1326 lev3map = (pt_entry_t *) 1326 lev3map = (pt_entry_t *)
1327 uvm_pageboot_alloc(sizeof(pt_entry_t) * lev3mapsize); 1327 uvm_pageboot_alloc(sizeof(pt_entry_t) * lev3mapsize);
1328 1328
1329 /* 1329 /*
1330 * Set up level 1 page table 1330 * Set up level 1 page table
1331 */ 1331 */
1332 1332
1333 /* Map all of the level 2 pte pages */ 1333 /* Map all of the level 2 pte pages */
1334 for (i = 0; i < howmany(lev2mapsize, NPTEPG); i++) { 1334 for (i = 0; i < howmany(lev2mapsize, NPTEPG); i++) {
1335 pte = (ALPHA_K0SEG_TO_PHYS(((vaddr_t)lev2map) + 1335 pte = (ALPHA_K0SEG_TO_PHYS(((vaddr_t)lev2map) +
1336 (i*PAGE_SIZE)) >> PGSHIFT) << PG_SHIFT; 1336 (i*PAGE_SIZE)) >> PGSHIFT) << PG_SHIFT;
1337 pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED; 1337 pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;
1338 kernel_lev1map[l1pte_index(VM_MIN_KERNEL_ADDRESS + 1338 kernel_lev1map[l1pte_index(VM_MIN_KERNEL_ADDRESS +
1339 (i*PAGE_SIZE*NPTEPG*NPTEPG))] = pte; 1339 (i*PAGE_SIZE*NPTEPG*NPTEPG))] = pte;
1340 } 1340 }
1341 1341
1342 /* Map the virtual page table */ 1342 /* Map the virtual page table */
1343 pte = (ALPHA_K0SEG_TO_PHYS((vaddr_t)kernel_lev1map) >> PGSHIFT) 1343 pte = (ALPHA_K0SEG_TO_PHYS((vaddr_t)kernel_lev1map) >> PGSHIFT)
1344 << PG_SHIFT; 1344 << PG_SHIFT;
1345 pte |= PG_V | PG_KRE | PG_KWE; /* NOTE NO ASM */ 1345 pte |= PG_V | PG_KRE | PG_KWE; /* NOTE NO ASM */
1346 kernel_lev1map[l1pte_index(VPTBASE)] = pte; 1346 kernel_lev1map[l1pte_index(VPTBASE)] = pte;
1347 VPT = (pt_entry_t *)VPTBASE; 1347 VPT = (pt_entry_t *)VPTBASE;
1348 1348
1349 /* 1349 /*
1350 * Set up level 2 page table. 1350 * Set up level 2 page table.
1351 */ 1351 */
1352 /* Map all of the level 3 pte pages */ 1352 /* Map all of the level 3 pte pages */
1353 for (i = 0; i < howmany(lev3mapsize, NPTEPG); i++) { 1353 for (i = 0; i < howmany(lev3mapsize, NPTEPG); i++) {
1354 pte = (ALPHA_K0SEG_TO_PHYS(((vaddr_t)lev3map) + 1354 pte = (ALPHA_K0SEG_TO_PHYS(((vaddr_t)lev3map) +
1355 (i*PAGE_SIZE)) >> PGSHIFT) << PG_SHIFT; 1355 (i*PAGE_SIZE)) >> PGSHIFT) << PG_SHIFT;
1356 pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED; 1356 pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;
1357 lev2map[l2pte_index(VM_MIN_KERNEL_ADDRESS+ 1357 lev2map[l2pte_index(VM_MIN_KERNEL_ADDRESS+
1358 (i*PAGE_SIZE*NPTEPG))] = pte; 1358 (i*PAGE_SIZE*NPTEPG))] = pte;
1359 } 1359 }
1360 1360
1361 /* Initialize the pmap_growkernel_lock. */ 1361 /* Initialize the pmap_growkernel_lock. */
1362 rw_init(&pmap_growkernel_lock); 1362 rw_init(&pmap_growkernel_lock);
1363 1363
1364 /* 1364 /*
1365 * Set up level three page table (lev3map) 1365 * Set up level three page table (lev3map)
1366 */ 1366 */
1367 /* Nothing to do; it's already zero'd */ 1367 /* Nothing to do; it's already zero'd */
1368 1368
1369 /* 1369 /*
1370 * Initialize the pmap pools and list. 1370 * Initialize the pmap pools and list.
1371 */ 1371 */
1372 pmap_ncpuids = ncpuids; 1372 pmap_ncpuids = ncpuids;
1373 pool_cache_bootstrap(&pmap_pmap_cache, PMAP_SIZEOF(pmap_ncpuids), 1373 pool_cache_bootstrap(&pmap_pmap_cache, PMAP_SIZEOF(pmap_ncpuids),
1374 COHERENCY_UNIT, 0, 0, "pmap", NULL, IPL_NONE, NULL, NULL, NULL); 1374 COHERENCY_UNIT, 0, 0, "pmap", NULL, IPL_NONE, NULL, NULL, NULL);
1375 pool_cache_bootstrap(&pmap_l1pt_cache, PAGE_SIZE, 0, 0, 0, "pmapl1pt", 1375 pool_cache_bootstrap(&pmap_l1pt_cache, PAGE_SIZE, 0, 0, 0, "pmapl1pt",
1376 &pmap_l1pt_allocator, IPL_NONE, pmap_l1pt_ctor, NULL, NULL); 1376 &pmap_l1pt_allocator, IPL_NONE, pmap_l1pt_ctor, NULL, NULL);
1377 pool_cache_bootstrap(&pmap_pv_cache, sizeof(struct pv_entry), 0, 0, 1377 pool_cache_bootstrap(&pmap_pv_cache, sizeof(struct pv_entry), 0, 0,
1378 PR_LARGECACHE, "pmappv", &pmap_pv_page_allocator, IPL_NONE, NULL, 1378 PR_LARGECACHE, "pmappv", &pmap_pv_page_allocator, IPL_NONE, NULL,
1379 NULL, NULL); 1379 NULL, NULL);
1380 1380
1381 TAILQ_INIT(&pmap_all_pmaps); 1381 TAILQ_INIT(&pmap_all_pmaps);
1382 1382
1383 /* Initialize the ASN logic. See also pmap_init_cpu(). */ 1383 /* Initialize the ASN logic. See also pmap_init_cpu(). */
1384 pmap_max_asn = maxasn; 1384 pmap_max_asn = maxasn;
1385 1385
1386 /* 1386 /*
1387 * Initialize the locks. 1387 * Initialize the locks.
1388 */ 1388 */
1389 rw_init(&pmap_main_lock); 1389 rw_init(&pmap_main_lock);
1390 mutex_init(&pmap_all_pmaps_lock, MUTEX_DEFAULT, IPL_NONE); 1390 mutex_init(&pmap_all_pmaps_lock, MUTEX_DEFAULT, IPL_NONE);
1391 for (i = 0; i < __arraycount(pmap_pvh_locks); i++) { 1391 for (i = 0; i < __arraycount(pmap_pvh_locks); i++) {
1392 mutex_init(&pmap_pvh_locks[i].lock, MUTEX_DEFAULT, IPL_NONE); 1392 mutex_init(&pmap_pvh_locks[i].lock, MUTEX_DEFAULT, IPL_NONE);
1393 } 1393 }
1394 for (i = 0; i < __arraycount(pmap_pvh_locks); i++) { 1394 for (i = 0; i < __arraycount(pmap_pvh_locks); i++) {
1395 mutex_init(&pmap_pmap_locks[i].locks.lock, 1395 mutex_init(&pmap_pmap_locks[i].locks.lock,
1396 MUTEX_DEFAULT, IPL_NONE); 1396 MUTEX_DEFAULT, IPL_NONE);
1397 mutex_init(&pmap_pmap_locks[i].locks.activation_lock, 1397 mutex_init(&pmap_pmap_locks[i].locks.activation_lock,
1398 MUTEX_SPIN, IPL_SCHED); 1398 MUTEX_SPIN, IPL_SCHED);
1399 } 1399 }
1400  1400
1401 /* 1401 /*
1402 * This must block any interrupt from which a TLB shootdown 1402 * This must block any interrupt from which a TLB shootdown
1403 * could be issued, but must NOT block IPIs. 1403 * could be issued, but must NOT block IPIs.
1404 */ 1404 */
1405 mutex_init(&tlb_lock, MUTEX_SPIN, IPL_VM); 1405 mutex_init(&tlb_lock, MUTEX_SPIN, IPL_VM);
1406 1406
1407 /* 1407 /*
1408 * Initialize kernel pmap. Note that all kernel mappings 1408 * Initialize kernel pmap. Note that all kernel mappings
1409 * have PG_ASM set, so the ASN doesn't really matter for 1409 * have PG_ASM set, so the ASN doesn't really matter for
1410 * the kernel pmap. Also, since the kernel pmap always 1410 * the kernel pmap. Also, since the kernel pmap always
1411 * references kernel_lev1map, it always has an invalid ASN 1411 * references kernel_lev1map, it always has an invalid ASN
1412 * generation. 1412 * generation.
1413 */ 1413 */
1414 memset(pmap_kernel(), 0, sizeof(struct pmap)); 1414 memset(pmap_kernel(), 0, sizeof(struct pmap));
1415 LIST_INIT(&pmap_kernel()->pm_ptpages); 1415 LIST_INIT(&pmap_kernel()->pm_ptpages);
1416 LIST_INIT(&pmap_kernel()->pm_pvents); 1416 LIST_INIT(&pmap_kernel()->pm_pvents);
1417 atomic_store_relaxed(&pmap_kernel()->pm_count, 1); 1417 atomic_store_relaxed(&pmap_kernel()->pm_count, 1);
1418 /* Kernel pmap does not have per-CPU info. */ 1418 /* Kernel pmap does not have per-CPU info. */
1419 TAILQ_INSERT_TAIL(&pmap_all_pmaps, pmap_kernel(), pm_list); 1419 TAILQ_INSERT_TAIL(&pmap_all_pmaps, pmap_kernel(), pm_list);
1420 1420
1421 /* 1421 /*
1422 * Set up lwp0's PCB such that the ptbr points to the right place 1422 * Set up lwp0's PCB such that the ptbr points to the right place
1423 * and has the kernel pmap's (really unused) ASN. 1423 * and has the kernel pmap's (really unused) ASN.
1424 */ 1424 */
1425 pcb = lwp_getpcb(&lwp0); 1425 pcb = lwp_getpcb(&lwp0);
1426 pcb->pcb_hw.apcb_ptbr = 1426 pcb->pcb_hw.apcb_ptbr =
1427 ALPHA_K0SEG_TO_PHYS((vaddr_t)kernel_lev1map) >> PGSHIFT; 1427 ALPHA_K0SEG_TO_PHYS((vaddr_t)kernel_lev1map) >> PGSHIFT;
1428 pcb->pcb_hw.apcb_asn = PMAP_ASN_KERNEL; 1428 pcb->pcb_hw.apcb_asn = PMAP_ASN_KERNEL;
1429 1429
1430 struct cpu_info * const ci = curcpu(); 1430 struct cpu_info * const ci = curcpu();
1431 pmap_init_cpu(ci); 1431 pmap_init_cpu(ci);
1432} 1432}
1433 1433
1434/* 1434/*
1435 * pmap_virtual_space: [ INTERFACE ] 1435 * pmap_virtual_space: [ INTERFACE ]
1436 * 1436 *
1437 * Define the initial bounds of the kernel virtual address space. 1437 * Define the initial bounds of the kernel virtual address space.
1438 */ 1438 */
1439void 1439void
1440pmap_virtual_space(vaddr_t *vstartp, vaddr_t *vendp) 1440pmap_virtual_space(vaddr_t *vstartp, vaddr_t *vendp)
1441{ 1441{
1442 1442
1443 *vstartp = VM_MIN_KERNEL_ADDRESS; /* kernel is in K0SEG */ 1443 *vstartp = VM_MIN_KERNEL_ADDRESS; /* kernel is in K0SEG */
1444 *vendp = VM_MAX_KERNEL_ADDRESS; /* we use pmap_growkernel */ 1444 *vendp = VM_MAX_KERNEL_ADDRESS; /* we use pmap_growkernel */
1445} 1445}
1446 1446
1447/* 1447/*
1448 * pmap_steal_memory: [ INTERFACE ] 1448 * pmap_steal_memory: [ INTERFACE ]
1449 * 1449 *
1450 * Bootstrap memory allocator (alternative to vm_bootstrap_steal_memory()). 1450 * Bootstrap memory allocator (alternative to vm_bootstrap_steal_memory()).
1451 * This function allows for early dynamic memory allocation until the 1451 * This function allows for early dynamic memory allocation until the
1452 * virtual memory system has been bootstrapped. After that point, either 1452 * virtual memory system has been bootstrapped. After that point, either
1453 * kmem_alloc or malloc should be used. This function works by stealing 1453 * kmem_alloc or malloc should be used. This function works by stealing
1454 * pages from the (to be) managed page pool, then implicitly mapping the 1454 * pages from the (to be) managed page pool, then implicitly mapping the
1455 * pages (by using their k0seg addresses) and zeroing them. 1455 * pages (by using their k0seg addresses) and zeroing them.
1456 * 1456 *
1457 * It may be used once the physical memory segments have been pre-loaded 1457 * It may be used once the physical memory segments have been pre-loaded
1458 * into the vm_physmem[] array. Early memory allocation MUST use this 1458 * into the vm_physmem[] array. Early memory allocation MUST use this
1459 * interface! This cannot be used after vm_page_startup(), and will 1459 * interface! This cannot be used after vm_page_startup(), and will
1460 * generate a panic if tried. 1460 * generate a panic if tried.
1461 * 1461 *
1462 * Note that this memory will never be freed, and in essence it is wired 1462 * Note that this memory will never be freed, and in essence it is wired
1463 * down. 1463 * down.
1464 * 1464 *
1465 * We must adjust *vstartp and/or *vendp iff we use address space 1465 * We must adjust *vstartp and/or *vendp iff we use address space
1466 * from the kernel virtual address range defined by pmap_virtual_space(). 1466 * from the kernel virtual address range defined by pmap_virtual_space().
1467 * 1467 *
1468 * Note: no locking is necessary in this function. 1468 * Note: no locking is necessary in this function.
1469 */ 1469 */
1470vaddr_t 1470vaddr_t
1471pmap_steal_memory(vsize_t size, vaddr_t *vstartp, vaddr_t *vendp) 1471pmap_steal_memory(vsize_t size, vaddr_t *vstartp, vaddr_t *vendp)
1472{ 1472{
1473 int npgs; 1473 int npgs;
1474 vaddr_t va; 1474 vaddr_t va;
1475 paddr_t pa; 1475 paddr_t pa;
1476 1476
1477 uvm_physseg_t bank; 1477 uvm_physseg_t bank;
1478 1478
1479 size = round_page(size); 1479 size = round_page(size);
1480 npgs = atop(size); 1480 npgs = atop(size);
1481 1481
1482#if 0 1482#if 0
1483 printf("PSM: size 0x%lx (npgs 0x%x)\n", size, npgs); 1483 printf("PSM: size 0x%lx (npgs 0x%x)\n", size, npgs);
1484#endif 1484#endif
1485 1485
1486 for (bank = uvm_physseg_get_first(); 1486 for (bank = uvm_physseg_get_first();
1487 uvm_physseg_valid_p(bank); 1487 uvm_physseg_valid_p(bank);
1488 bank = uvm_physseg_get_next(bank)) { 1488 bank = uvm_physseg_get_next(bank)) {
1489 if (uvm.page_init_done == true) 1489 if (uvm.page_init_done == true)
1490 panic("pmap_steal_memory: called _after_ bootstrap"); 1490 panic("pmap_steal_memory: called _after_ bootstrap");
1491 1491
1492#if 0 1492#if 0
1493 printf(" bank %d: avail_start 0x%"PRIxPADDR", start 0x%"PRIxPADDR", " 1493 printf(" bank %d: avail_start 0x%"PRIxPADDR", start 0x%"PRIxPADDR", "
1494 "avail_end 0x%"PRIxPADDR"\n", bank, uvm_physseg_get_avail_start(bank), 1494 "avail_end 0x%"PRIxPADDR"\n", bank, uvm_physseg_get_avail_start(bank),
1495 uvm_physseg_get_start(bank), uvm_physseg_get_avail_end(bank)); 1495 uvm_physseg_get_start(bank), uvm_physseg_get_avail_end(bank));
1496#endif 1496#endif
1497 1497
1498 if (uvm_physseg_get_avail_start(bank) != uvm_physseg_get_start(bank) || 1498 if (uvm_physseg_get_avail_start(bank) != uvm_physseg_get_start(bank) ||
1499 uvm_physseg_get_avail_start(bank) >= uvm_physseg_get_avail_end(bank)) 1499 uvm_physseg_get_avail_start(bank) >= uvm_physseg_get_avail_end(bank))
1500 continue; 1500 continue;
1501 1501
1502#if 0 1502#if 0
1503 printf(" avail_end - avail_start = 0x%"PRIxPADDR"\n", 1503 printf(" avail_end - avail_start = 0x%"PRIxPADDR"\n",
1504 uvm_physseg_get_avail_end(bank) - uvm_physseg_get_avail_start(bank)); 1504 uvm_physseg_get_avail_end(bank) - uvm_physseg_get_avail_start(bank));
1505#endif 1505#endif
1506 1506
1507 if (uvm_physseg_get_avail_end(bank) - uvm_physseg_get_avail_start(bank) 1507 if (uvm_physseg_get_avail_end(bank) - uvm_physseg_get_avail_start(bank)
1508 < npgs) 1508 < npgs)
1509 continue; 1509 continue;
1510 1510
1511 /* 1511 /*
1512 * There are enough pages here; steal them! 1512 * There are enough pages here; steal them!
1513 */ 1513 */
1514 pa = ptoa(uvm_physseg_get_start(bank)); 1514 pa = ptoa(uvm_physseg_get_start(bank));
1515 uvm_physseg_unplug(atop(pa), npgs); 1515 uvm_physseg_unplug(atop(pa), npgs);
1516 1516
1517 va = ALPHA_PHYS_TO_K0SEG(pa); 1517 va = ALPHA_PHYS_TO_K0SEG(pa);
1518 memset((void *)va, 0, size); 1518 memset((void *)va, 0, size);
1519 pmap_pages_stolen += npgs; 1519 pmap_pages_stolen += npgs;
1520 return (va); 1520 return (va);
1521 } 1521 }
1522 1522
1523 /* 1523 /*
1524 * If we got here, this was no memory left. 1524 * If we got here, this was no memory left.
1525 */ 1525 */
1526 panic("pmap_steal_memory: no memory to steal"); 1526 panic("pmap_steal_memory: no memory to steal");
1527} 1527}
1528 1528
1529/* 1529/*
1530 * pmap_init: [ INTERFACE ] 1530 * pmap_init: [ INTERFACE ]
1531 * 1531 *
1532 * Initialize the pmap module. Called by vm_init(), to initialize any 1532 * Initialize the pmap module. Called by vm_init(), to initialize any
1533 * structures that the pmap system needs to map virtual memory. 1533 * structures that the pmap system needs to map virtual memory.
1534 * 1534 *
1535 * Note: no locking is necessary in this function. 1535 * Note: no locking is necessary in this function.
1536 */ 1536 */
1537void 1537void
1538pmap_init(void) 1538pmap_init(void)
1539{ 1539{
1540 1540
1541#ifdef DEBUG 1541#ifdef DEBUG
1542 if (pmapdebug & PDB_FOLLOW) 1542 if (pmapdebug & PDB_FOLLOW)
1543 printf("pmap_init()\n"); 1543 printf("pmap_init()\n");
1544#endif 1544#endif
1545 1545
1546 /* initialize protection array */ 1546 /* initialize protection array */
1547 alpha_protection_init(); 1547 alpha_protection_init();
1548 1548
1549 /* Initialize TLB handling. */ 1549 /* Initialize TLB handling. */
1550 pmap_tlb_init(); 1550 pmap_tlb_init();
1551 1551
1552 /* 1552 /*
1553 * Set a low water mark on the pv_entry pool, so that we are 1553 * Set a low water mark on the pv_entry pool, so that we are
1554 * more likely to have these around even in extreme memory 1554 * more likely to have these around even in extreme memory
1555 * starvation. 1555 * starvation.
1556 */ 1556 */
1557 pool_cache_setlowat(&pmap_pv_cache, pmap_pv_lowat); 1557 pool_cache_setlowat(&pmap_pv_cache, pmap_pv_lowat);
1558 1558
1559 /* 1559 /*
1560 * Now it is safe to enable pv entry recording. 1560 * Now it is safe to enable pv entry recording.
1561 */ 1561 */
1562 pmap_initialized = true; 1562 pmap_initialized = true;
1563 1563
1564#if 0 1564#if 0
1565 for (uvm_physseg_t bank = uvm_physseg_get_first(); 1565 for (uvm_physseg_t bank = uvm_physseg_get_first();
1566 uvm_physseg_valid_p(bank); 1566 uvm_physseg_valid_p(bank);
1567 bank = uvm_physseg_get_next(bank)) { 1567 bank = uvm_physseg_get_next(bank)) {
1568 printf("bank %d\n", bank); 1568 printf("bank %d\n", bank);
1569 printf("\tstart = 0x%lx\n", ptoa(uvm_physseg_get_start(bank))); 1569 printf("\tstart = 0x%lx\n", ptoa(uvm_physseg_get_start(bank)));
1570 printf("\tend = 0x%lx\n", ptoa(uvm_physseg_get_end(bank))); 1570 printf("\tend = 0x%lx\n", ptoa(uvm_physseg_get_end(bank)));
1571 printf("\tavail_start = 0x%lx\n", 1571 printf("\tavail_start = 0x%lx\n",
1572 ptoa(uvm_physseg_get_avail_start(bank))); 1572 ptoa(uvm_physseg_get_avail_start(bank)));
1573 printf("\tavail_end = 0x%lx\n", 1573 printf("\tavail_end = 0x%lx\n",
1574 ptoa(uvm_physseg_get_avail_end(bank))); 1574 ptoa(uvm_physseg_get_avail_end(bank)));
1575 } 1575 }
1576#endif 1576#endif
1577} 1577}
1578 1578
1579/* 1579/*
1580 * pmap_create: [ INTERFACE ] 1580 * pmap_create: [ INTERFACE ]
1581 * 1581 *
1582 * Create and return a physical map. 1582 * Create and return a physical map.
1583 * 1583 *
1584 * Note: no locking is necessary in this function. 1584 * Note: no locking is necessary in this function.
1585 */ 1585 */
1586pmap_t 1586pmap_t
1587pmap_create(void) 1587pmap_create(void)
1588{ 1588{
1589 pmap_t pmap; 1589 pmap_t pmap;
1590 pt_entry_t *lev1map; 1590 pt_entry_t *lev1map;
1591 int i; 1591 int i;
1592 1592
1593#ifdef DEBUG 1593#ifdef DEBUG
1594 if (pmapdebug & (PDB_FOLLOW|PDB_CREATE)) 1594 if (pmapdebug & (PDB_FOLLOW|PDB_CREATE))
1595 printf("pmap_create()\n"); 1595 printf("pmap_create()\n");
1596#endif 1596#endif
1597 1597
1598 pmap = pool_cache_get(&pmap_pmap_cache, PR_WAITOK); 1598 pmap = pool_cache_get(&pmap_pmap_cache, PR_WAITOK);
1599 memset(pmap, 0, sizeof(*pmap)); 1599 memset(pmap, 0, sizeof(*pmap));
1600 LIST_INIT(&pmap->pm_ptpages); 1600 LIST_INIT(&pmap->pm_ptpages);
1601 LIST_INIT(&pmap->pm_pvents); 1601 LIST_INIT(&pmap->pm_pvents);
1602 1602
1603 atomic_store_relaxed(&pmap->pm_count, 1); 1603 atomic_store_relaxed(&pmap->pm_count, 1);
1604 1604
1605 try_again: 1605 try_again:
1606 rw_enter(&pmap_growkernel_lock, RW_READER); 1606 rw_enter(&pmap_growkernel_lock, RW_READER);
1607 1607
1608 lev1map = pool_cache_get(&pmap_l1pt_cache, PR_NOWAIT); 1608 lev1map = pool_cache_get(&pmap_l1pt_cache, PR_NOWAIT);
1609 if (__predict_false(lev1map == NULL)) { 1609 if (__predict_false(lev1map == NULL)) {
1610 rw_exit(&pmap_growkernel_lock); 1610 rw_exit(&pmap_growkernel_lock);
1611 (void) kpause("pmap_create", false, hz >> 2, NULL); 1611 (void) kpause("pmap_create", false, hz >> 2, NULL);
1612 goto try_again; 1612 goto try_again;
1613 } 1613 }
1614 1614
1615 /* 1615 /*
1616 * There are only kernel mappings at this point; give the pmap 1616 * There are only kernel mappings at this point; give the pmap
1617 * the kernel ASN. This will be initialized to correct values 1617 * the kernel ASN. This will be initialized to correct values
1618 * when the pmap is activated. 1618 * when the pmap is activated.
1619 * 1619 *
1620 * We stash a pointer to the pmap's lev1map in each CPU's 1620 * We stash a pointer to the pmap's lev1map in each CPU's
1621 * private data. It remains constant for the life of the 1621 * private data. It remains constant for the life of the
1622 * pmap, and gives us more room in the shared pmap structure. 1622 * pmap, and gives us more room in the shared pmap structure.
1623 */ 1623 */
1624 for (i = 0; i < pmap_ncpuids; i++) { 1624 for (i = 0; i < pmap_ncpuids; i++) {
1625 pmap->pm_percpu[i].pmc_asn = PMAP_ASN_KERNEL; 1625 pmap->pm_percpu[i].pmc_asn = PMAP_ASN_KERNEL;
1626 pmap->pm_percpu[i].pmc_asngen = PMAP_ASNGEN_INVALID; 1626 pmap->pm_percpu[i].pmc_asngen = PMAP_ASNGEN_INVALID;
1627 pmap->pm_percpu[i].pmc_lev1map = lev1map; 1627 pmap->pm_percpu[i].pmc_lev1map = lev1map;
1628 } 1628 }
1629 1629
1630 mutex_enter(&pmap_all_pmaps_lock); 1630 mutex_enter(&pmap_all_pmaps_lock);
1631 TAILQ_INSERT_TAIL(&pmap_all_pmaps, pmap, pm_list); 1631 TAILQ_INSERT_TAIL(&pmap_all_pmaps, pmap, pm_list);
1632 mutex_exit(&pmap_all_pmaps_lock); 1632 mutex_exit(&pmap_all_pmaps_lock);
1633 1633
1634 rw_exit(&pmap_growkernel_lock); 1634 rw_exit(&pmap_growkernel_lock);
1635 1635
1636 return (pmap); 1636 return (pmap);
1637} 1637}
1638 1638
1639/* 1639/*
1640 * pmap_destroy: [ INTERFACE ] 1640 * pmap_destroy: [ INTERFACE ]
1641 * 1641 *
1642 * Drop the reference count on the specified pmap, releasing 1642 * Drop the reference count on the specified pmap, releasing
1643 * all resources if the reference count drops to zero. 1643 * all resources if the reference count drops to zero.
1644 */ 1644 */
1645void 1645void
1646pmap_destroy(pmap_t pmap) 1646pmap_destroy(pmap_t pmap)
1647{ 1647{
1648 1648
1649#ifdef DEBUG 1649#ifdef DEBUG
1650 if (pmapdebug & PDB_FOLLOW) 1650 if (pmapdebug & PDB_FOLLOW)
1651 printf("pmap_destroy(%p)\n", pmap); 1651 printf("pmap_destroy(%p)\n", pmap);
1652#endif 1652#endif
1653 1653
1654 PMAP_MP(membar_exit()); 1654 PMAP_MP(membar_exit());
1655 KASSERT(atomic_load_relaxed(&pmap->pm_count) > 0); 1655 KASSERT(atomic_load_relaxed(&pmap->pm_count) > 0);
1656 if (atomic_dec_uint_nv(&pmap->pm_count) > 0) 1656 if (atomic_dec_uint_nv(&pmap->pm_count) > 0)
1657 return; 1657 return;
1658 1658
1659 pt_entry_t *lev1map = pmap_lev1map(pmap); 1659 pt_entry_t *lev1map = pmap_lev1map(pmap);
1660 1660
1661 rw_enter(&pmap_growkernel_lock, RW_READER); 1661 rw_enter(&pmap_growkernel_lock, RW_READER);
1662 1662
1663 /* 1663 /*
1664 * Remove it from the global list of all pmaps. 1664 * Remove it from the global list of all pmaps.
1665 */ 1665 */
1666 mutex_enter(&pmap_all_pmaps_lock); 1666 mutex_enter(&pmap_all_pmaps_lock);
1667 TAILQ_REMOVE(&pmap_all_pmaps, pmap, pm_list); 1667 TAILQ_REMOVE(&pmap_all_pmaps, pmap, pm_list);
1668 mutex_exit(&pmap_all_pmaps_lock); 1668 mutex_exit(&pmap_all_pmaps_lock);
1669 1669
1670 pool_cache_put(&pmap_l1pt_cache, lev1map); 1670 pool_cache_put(&pmap_l1pt_cache, lev1map);
1671#ifdef DIAGNOSTIC 1671#ifdef DIAGNOSTIC
1672 int i; 1672 int i;
1673 for (i = 0; i < pmap_ncpuids; i++) { 1673 for (i = 0; i < pmap_ncpuids; i++) {
1674 pmap->pm_percpu[i].pmc_lev1map = (pt_entry_t *)0xdeadbeefUL; 1674 pmap->pm_percpu[i].pmc_lev1map = (pt_entry_t *)0xdeadbeefUL;
1675 } 1675 }
1676#endif /* DIAGNOSTIC */ 1676#endif /* DIAGNOSTIC */
1677 1677
1678 rw_exit(&pmap_growkernel_lock); 1678 rw_exit(&pmap_growkernel_lock);
1679 1679
1680 pool_cache_put(&pmap_pmap_cache, pmap); 1680 pool_cache_put(&pmap_pmap_cache, pmap);
1681} 1681}
1682 1682
1683/* 1683/*
1684 * pmap_reference: [ INTERFACE ] 1684 * pmap_reference: [ INTERFACE ]
1685 * 1685 *
1686 * Add a reference to the specified pmap. 1686 * Add a reference to the specified pmap.
1687 */ 1687 */
1688void 1688void
1689pmap_reference(pmap_t pmap) 1689pmap_reference(pmap_t pmap)
1690{ 1690{
1691 unsigned int newcount __diagused; 1691 unsigned int newcount __diagused;
1692 1692
1693#ifdef DEBUG 1693#ifdef DEBUG
1694 if (pmapdebug & PDB_FOLLOW) 1694 if (pmapdebug & PDB_FOLLOW)
1695 printf("pmap_reference(%p)\n", pmap); 1695 printf("pmap_reference(%p)\n", pmap);
1696#endif 1696#endif
1697 1697
1698 newcount = atomic_inc_uint_nv(&pmap->pm_count); 1698 newcount = atomic_inc_uint_nv(&pmap->pm_count);
1699 KASSERT(newcount != 0); 1699 KASSERT(newcount != 0);
1700 PMAP_MP(membar_enter()); 1700 PMAP_MP(membar_enter());
1701} 1701}
1702 1702
1703/* 1703/*
1704 * pmap_remove: [ INTERFACE ] 1704 * pmap_remove: [ INTERFACE ]
1705 * 1705 *
1706 * Remove the given range of addresses from the specified map. 1706 * Remove the given range of addresses from the specified map.
1707 * 1707 *
1708 * It is assumed that the start and end are properly 1708 * It is assumed that the start and end are properly
1709 * rounded to the page size. 1709 * rounded to the page size.
1710 */ 1710 */
1711static void 1711static void
1712pmap_remove_internal(pmap_t pmap, vaddr_t sva, vaddr_t eva, 1712pmap_remove_internal(pmap_t pmap, vaddr_t sva, vaddr_t eva,
1713 struct pmap_tlb_context * const tlbctx) 1713 struct pmap_tlb_context * const tlbctx)
1714{ 1714{
1715 pt_entry_t *l1pte, *l2pte, *l3pte; 1715 pt_entry_t *l1pte, *l2pte, *l3pte;
1716 pt_entry_t *saved_l2pte, *saved_l3pte; 1716 pt_entry_t *saved_l2pte, *saved_l3pte;
1717 vaddr_t l1eva, l2eva, l3vptva; 1717 vaddr_t l1eva, l2eva, l3vptva;
1718 pt_entry_t pte_bits; 1718 pt_entry_t pte_bits;
1719 1719
1720#ifdef DEBUG 1720#ifdef DEBUG
1721 if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT)) 1721 if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT))
1722 printf("pmap_remove(%p, %lx, %lx)\n", pmap, sva, eva); 1722 printf("pmap_remove(%p, %lx, %lx)\n", pmap, sva, eva);
1723#endif 1723#endif
1724 1724
1725 /* 1725 /*
1726 * If this is the kernel pmap, we can use a faster method 1726 * If this is the kernel pmap, we can use a faster method
1727 * for accessing the PTEs (since the PT pages are always 1727 * for accessing the PTEs (since the PT pages are always
1728 * resident). 1728 * resident).
1729 * 1729 *
1730 * Note that this routine should NEVER be called from an 1730 * Note that this routine should NEVER be called from an
1731 * interrupt context; pmap_kremove() is used for that. 1731 * interrupt context; pmap_kremove() is used for that.
1732 */ 1732 */
1733 if (pmap == pmap_kernel()) { 1733 if (pmap == pmap_kernel()) {
1734 PMAP_MAP_TO_HEAD_LOCK(); 1734 PMAP_MAP_TO_HEAD_LOCK();
1735 PMAP_LOCK(pmap); 1735 PMAP_LOCK(pmap);
1736 1736
1737 while (sva < eva) { 1737 while (sva < eva) {
1738 l3pte = PMAP_KERNEL_PTE(sva); 1738 l3pte = PMAP_KERNEL_PTE(sva);
1739 if (pmap_pte_v(l3pte)) { 1739 if (pmap_pte_v(l3pte)) {
1740 pte_bits = pmap_remove_mapping(pmap, sva, 1740 pte_bits = pmap_remove_mapping(pmap, sva,
1741 l3pte, true, NULL, tlbctx); 1741 l3pte, true, NULL, tlbctx);
1742 pmap_tlb_shootdown(pmap, sva, pte_bits, 1742 pmap_tlb_shootdown(pmap, sva, pte_bits,
1743 tlbctx); 1743 tlbctx);
1744 } 1744 }
1745 sva += PAGE_SIZE; 1745 sva += PAGE_SIZE;
1746 } 1746 }
1747 1747
1748 PMAP_MAP_TO_HEAD_UNLOCK(); 1748 PMAP_MAP_TO_HEAD_UNLOCK();
1749 PMAP_UNLOCK(pmap); 1749 PMAP_UNLOCK(pmap);
1750 pmap_tlb_shootnow(tlbctx); 1750 pmap_tlb_shootnow(tlbctx);
1751 /* kernel PT pages are never freed. */ 1751 /* kernel PT pages are never freed. */
1752 KASSERT(LIST_EMPTY(&tlbctx->t_freeptq)); 1752 KASSERT(LIST_EMPTY(&tlbctx->t_freeptq));
1753 /* ...but we might have freed PV entries. */ 1753 /* ...but we might have freed PV entries. */
1754 pmap_tlb_context_drain(tlbctx); 1754 pmap_tlb_context_drain(tlbctx);
1755 TLB_COUNT(reason_remove_kernel); 1755 TLB_COUNT(reason_remove_kernel);
1756 1756
1757 return; 1757 return;
1758 } 1758 }
1759 1759
1760 pt_entry_t * const lev1map = pmap_lev1map(pmap); 1760 pt_entry_t * const lev1map = pmap_lev1map(pmap);
1761 1761
1762 KASSERT(sva < VM_MAXUSER_ADDRESS); 1762 KASSERT(sva < VM_MAXUSER_ADDRESS);
1763 KASSERT(eva <= VM_MAXUSER_ADDRESS); 1763 KASSERT(eva <= VM_MAXUSER_ADDRESS);
1764 KASSERT(lev1map != kernel_lev1map); 1764 KASSERT(lev1map != kernel_lev1map);
1765 1765
1766 PMAP_MAP_TO_HEAD_LOCK(); 1766 PMAP_MAP_TO_HEAD_LOCK();
1767 PMAP_LOCK(pmap); 1767 PMAP_LOCK(pmap);
1768 1768
1769 l1pte = pmap_l1pte(lev1map, sva); 1769 l1pte = pmap_l1pte(lev1map, sva);
1770 1770
1771 for (; sva < eva; sva = l1eva, l1pte++) { 1771 for (; sva < eva; sva = l1eva, l1pte++) {
1772 l1eva = alpha_trunc_l1seg(sva) + ALPHA_L1SEG_SIZE; 1772 l1eva = alpha_trunc_l1seg(sva) + ALPHA_L1SEG_SIZE;
1773 if (pmap_pte_v(l1pte)) { 1773 if (pmap_pte_v(l1pte)) {
1774 saved_l2pte = l2pte = pmap_l2pte(lev1map, sva, l1pte); 1774 saved_l2pte = l2pte = pmap_l2pte(lev1map, sva, l1pte);
1775 1775
1776 /* 1776 /*
1777 * Add a reference to the L2 table so it won't 1777 * Add a reference to the L2 table so it won't
1778 * get removed from under us. 1778 * get removed from under us.
1779 */ 1779 */
1780 pmap_physpage_addref(saved_l2pte); 1780 pmap_physpage_addref(saved_l2pte);
1781 1781
1782 for (; sva < l1eva && sva < eva; sva = l2eva, l2pte++) { 1782 for (; sva < l1eva && sva < eva; sva = l2eva, l2pte++) {
1783 l2eva = 1783 l2eva =
1784 alpha_trunc_l2seg(sva) + ALPHA_L2SEG_SIZE; 1784 alpha_trunc_l2seg(sva) + ALPHA_L2SEG_SIZE;
1785 if (pmap_pte_v(l2pte)) { 1785 if (pmap_pte_v(l2pte)) {
1786 saved_l3pte = l3pte = 1786 saved_l3pte = l3pte =
1787 pmap_l3pte(lev1map, sva, l2pte); 1787 pmap_l3pte(lev1map, sva, l2pte);
1788 1788
1789 /* 1789 /*
1790 * Add a reference to the L3 table so 1790 * Add a reference to the L3 table so
1791 * it won't get removed from under us. 1791 * it won't get removed from under us.
1792 */ 1792 */
1793 pmap_physpage_addref(saved_l3pte); 1793 pmap_physpage_addref(saved_l3pte);
1794 1794
1795 /* 1795 /*
1796 * Remember this sva; if the L3 table 1796 * Remember this sva; if the L3 table
1797 * gets removed, we need to invalidate 1797 * gets removed, we need to invalidate
1798 * the VPT TLB entry for it. 1798 * the VPT TLB entry for it.
1799 */ 1799 */
1800 l3vptva = sva; 1800 l3vptva = sva;
1801 1801
1802 for (; sva < l2eva && sva < eva; 1802 for (; sva < l2eva && sva < eva;
1803 sva += PAGE_SIZE, l3pte++) { 1803 sva += PAGE_SIZE, l3pte++) {
1804 if (!pmap_pte_v(l3pte)) { 1804 if (!pmap_pte_v(l3pte)) {
1805 continue; 1805 continue;
1806 } 1806 }
1807 pte_bits = 1807 pte_bits =
1808 pmap_remove_mapping( 1808 pmap_remove_mapping(
1809 pmap, sva, 1809 pmap, sva,
1810 l3pte, true, 1810 l3pte, true,
1811 NULL, tlbctx); 1811 NULL, tlbctx);
1812 pmap_tlb_shootdown(pmap, 1812 pmap_tlb_shootdown(pmap,
1813 sva, pte_bits, tlbctx); 1813 sva, pte_bits, tlbctx);
1814 } 1814 }
1815 1815
1816 /* 1816 /*
1817 * Remove the reference to the L3 1817 * Remove the reference to the L3
1818 * table that we added above. This 1818 * table that we added above. This
1819 * may free the L3 table. 1819 * may free the L3 table.
1820 */ 1820 */
1821 pmap_l3pt_delref(pmap, l3vptva, 1821 pmap_l3pt_delref(pmap, l3vptva,
1822 saved_l3pte, tlbctx); 1822 saved_l3pte, tlbctx);
1823 } 1823 }
1824 } 1824 }
1825 1825
1826 /* 1826 /*
1827 * Remove the reference to the L2 table that we 1827 * Remove the reference to the L2 table that we
1828 * added above. This may free the L2 table. 1828 * added above. This may free the L2 table.
1829 */ 1829 */
1830 pmap_l2pt_delref(pmap, l1pte, saved_l2pte, tlbctx); 1830 pmap_l2pt_delref(pmap, l1pte, saved_l2pte, tlbctx);
1831 } 1831 }
1832 } 1832 }
1833 1833
1834 PMAP_MAP_TO_HEAD_UNLOCK(); 1834 PMAP_MAP_TO_HEAD_UNLOCK();
1835 PMAP_UNLOCK(pmap); 1835 PMAP_UNLOCK(pmap);
1836 pmap_tlb_shootnow(tlbctx); 1836 pmap_tlb_shootnow(tlbctx);
1837 pmap_tlb_context_drain(tlbctx); 1837 pmap_tlb_context_drain(tlbctx);
1838 TLB_COUNT(reason_remove_user); 1838 TLB_COUNT(reason_remove_user);
1839} 1839}
1840 1840
1841void 1841void
1842pmap_remove(pmap_t pmap, vaddr_t sva, vaddr_t eva) 1842pmap_remove(pmap_t pmap, vaddr_t sva, vaddr_t eva)
1843{ 1843{
1844 struct pmap_tlb_context tlbctx; 1844 struct pmap_tlb_context tlbctx;
1845 1845
1846 pmap_tlb_context_init(&tlbctx, 0); 1846 pmap_tlb_context_init(&tlbctx, 0);
1847 pmap_remove_internal(pmap, sva, eva, &tlbctx); 1847 pmap_remove_internal(pmap, sva, eva, &tlbctx);
1848} 1848}
1849 1849
1850/* 1850/*
1851 * pmap_remove_all: [ INTERFACE ] 1851 * pmap_remove_all: [ INTERFACE ]
1852 * 1852 *
1853 * Remove all mappings from a pmap in bulk. This is only called 1853 * Remove all mappings from a pmap in bulk. This is only called
1854 * when it's known that the address space is no longer visible to 1854 * when it's known that the address space is no longer visible to
1855 * any user process (e.g. during exit or exec). 1855 * any user process (e.g. during exit or exec).
1856 */ 1856 */
1857bool 1857bool
1858pmap_remove_all(pmap_t pmap) 1858pmap_remove_all(pmap_t pmap)
1859{ 1859{
1860 struct pmap_tlb_context tlbctx; 1860 struct pmap_tlb_context tlbctx;
1861 struct vm_page *pg; 1861 struct vm_page *pg;
1862 pv_entry_t pv; 1862 pv_entry_t pv;
1863 1863
1864 KASSERT(pmap != pmap_kernel()); 1864 KASSERT(pmap != pmap_kernel());
1865 1865
1866 /* 1866 /*
1867 * This process is pretty simple: 1867 * This process is pretty simple:
1868 * 1868 *
1869 * ==> (1) Zero out the user-space portion of the lev1map. 1869 * ==> (1) Zero out the user-space portion of the lev1map.
1870 * 1870 *
1871 * ==> (2) Copy the PT page list to the tlbctx and re-init. 1871 * ==> (2) Copy the PT page list to the tlbctx and re-init.
1872 * 1872 *
1873 * ==> (3) Walk the PV entry list and remove each entry. 1873 * ==> (3) Walk the PV entry list and remove each entry.
1874 * 1874 *
1875 * ==> (4) Zero the wired and resident count. 1875 * ==> (4) Zero the wired and resident count.
1876 * 1876 *
1877 * Once we've done that, we just need to free everything 1877 * Once we've done that, we just need to free everything
1878 * back to the system. 1878 * back to the system.
1879 */ 1879 */
1880 1880
1881 pmap_tlb_context_init(&tlbctx, 0); 1881 pmap_tlb_context_init(&tlbctx, 0);
1882 1882
1883 PMAP_MAP_TO_HEAD_LOCK(); 1883 PMAP_MAP_TO_HEAD_LOCK();
1884 PMAP_LOCK(pmap); 1884 PMAP_LOCK(pmap);
1885 1885
1886 /* Step 1 */ 1886 /* Step 1 */
1887 pt_entry_t * const lev1map = pmap_lev1map(pmap); 1887 pt_entry_t * const lev1map = pmap_lev1map(pmap);
1888 memset(lev1map, 0, 1888 memset(lev1map, 0,
1889 l1pte_index(VM_MAXUSER_ADDRESS) * sizeof(pt_entry_t)); 1889 l1pte_index(VM_MAXUSER_ADDRESS) * sizeof(pt_entry_t));
1890 1890
1891 /* Step 2 */ 1891 /* Step 2 */
1892 LIST_MOVE(&pmap->pm_ptpages, &tlbctx.t_freeptq, pageq.list); 1892 LIST_MOVE(&pmap->pm_ptpages, &tlbctx.t_freeptq, pageq.list);
1893 1893
1894 /* Fix up the reference count on the lev1map page. */ 1894 /* Fix up the reference count on the lev1map page. */
1895 pg = PHYS_TO_VM_PAGE(ALPHA_K0SEG_TO_PHYS((vaddr_t)lev1map)); 1895 pg = PHYS_TO_VM_PAGE(ALPHA_K0SEG_TO_PHYS((vaddr_t)lev1map));
1896 atomic_store_relaxed(&pg->loan_count, 0); 1896 atomic_store_relaxed(&pg->loan_count, 0);
1897 1897
1898 /* Step 3 */ 1898 /* Step 3 */
1899 while ((pv = LIST_FIRST(&pmap->pm_pvents)) != NULL) { 1899 while ((pv = LIST_FIRST(&pmap->pm_pvents)) != NULL) {
1900 KASSERT(pv->pv_pmap == pmap); 1900 KASSERT(pv->pv_pmap == pmap);
1901 pmap_pv_remove(pmap, PHYS_TO_VM_PAGE(pmap_pte_pa(pv->pv_pte)), 1901 pmap_pv_remove(pmap, PHYS_TO_VM_PAGE(pmap_pte_pa(pv->pv_pte)),
1902 pv->pv_va, true, NULL, &tlbctx); 1902 pv->pv_va, true, NULL, &tlbctx);
1903 } 1903 }
1904 1904
1905 /* Step 4 */ 1905 /* Step 4 */
1906 atomic_store_relaxed(&pmap->pm_stats.wired_count, 0); 1906 atomic_store_relaxed(&pmap->pm_stats.wired_count, 0);
1907 atomic_store_relaxed(&pmap->pm_stats.resident_count, 0); 1907 atomic_store_relaxed(&pmap->pm_stats.resident_count, 0);
1908 1908
1909 pmap_tlb_shootdown_all_user(pmap, PG_EXEC, &tlbctx); 1909 pmap_tlb_shootdown_all_user(pmap, PG_EXEC, &tlbctx);
1910 1910
1911 PMAP_UNLOCK(pmap); 1911 PMAP_UNLOCK(pmap);
1912 PMAP_MAP_TO_HEAD_UNLOCK(); 1912 PMAP_MAP_TO_HEAD_UNLOCK();
1913 1913
1914 pmap_tlb_shootnow(&tlbctx); 1914 pmap_tlb_shootnow(&tlbctx);
1915 pmap_tlb_context_drain(&tlbctx); 1915 pmap_tlb_context_drain(&tlbctx);
1916 TLB_COUNT(reason_remove_all_user); 1916 TLB_COUNT(reason_remove_all_user);
1917 1917
1918 return true; 1918 return true;
1919} 1919}
1920 1920
1921/* 1921/*
1922 * pmap_page_protect: [ INTERFACE ] 1922 * pmap_page_protect: [ INTERFACE ]
1923 * 1923 *
1924 * Lower the permission for all mappings to a given page to 1924 * Lower the permission for all mappings to a given page to
1925 * the permissions specified. 1925 * the permissions specified.
1926 */ 1926 */
1927void 1927void
1928pmap_page_protect(struct vm_page *pg, vm_prot_t prot) 1928pmap_page_protect(struct vm_page *pg, vm_prot_t prot)
1929{ 1929{
1930 pv_entry_t pv, nextpv; 1930 pv_entry_t pv, nextpv;
1931 pt_entry_t opte; 1931 pt_entry_t opte;
1932 kmutex_t *lock; 1932 kmutex_t *lock;
1933 struct pmap_tlb_context tlbctx; 1933 struct pmap_tlb_context tlbctx;
1934 1934
1935#ifdef DEBUG 1935#ifdef DEBUG
1936 paddr_t pa = VM_PAGE_TO_PHYS(pg); 
1937 
1938 
1939 if ((pmapdebug & (PDB_FOLLOW|PDB_PROTECT)) || 1936 if ((pmapdebug & (PDB_FOLLOW|PDB_PROTECT)) ||
1940 (prot == VM_PROT_NONE && (pmapdebug & PDB_REMOVE))) 1937 (prot == VM_PROT_NONE && (pmapdebug & PDB_REMOVE)))
1941 printf("pmap_page_protect(%p, %x)\n", pg, prot); 1938 printf("pmap_page_protect(%p, %x)\n", pg, prot);
1942#endif 1939#endif
1943 1940
1944 pmap_tlb_context_init(&tlbctx, TLB_CTX_F_PV); 1941 pmap_tlb_context_init(&tlbctx, TLB_CTX_F_PV);
1945 1942
1946 switch (prot) { 1943 switch (prot) {
1947 case VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE: 1944 case VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE:
1948 case VM_PROT_READ|VM_PROT_WRITE: 1945 case VM_PROT_READ|VM_PROT_WRITE:
1949 return; 1946 return;
1950 1947
1951 /* copy_on_write */ 1948 /* copy_on_write */
1952 case VM_PROT_READ|VM_PROT_EXECUTE: 1949 case VM_PROT_READ|VM_PROT_EXECUTE:
1953 case VM_PROT_READ: 1950 case VM_PROT_READ:
1954 PMAP_HEAD_TO_MAP_LOCK(); 1951 PMAP_HEAD_TO_MAP_LOCK();
1955 lock = pmap_pvh_lock(pg); 1952 lock = pmap_pvh_lock(pg);
1956 mutex_enter(lock); 1953 mutex_enter(lock);
1957 for (pv = VM_MDPAGE_PVS(pg); pv != NULL; pv = pv->pv_next) { 1954 for (pv = VM_MDPAGE_PVS(pg); pv != NULL; pv = pv->pv_next) {
1958 PMAP_LOCK(pv->pv_pmap); 1955 PMAP_LOCK(pv->pv_pmap);
1959 opte = atomic_load_relaxed(pv->pv_pte); 1956 opte = atomic_load_relaxed(pv->pv_pte);
1960 if (opte & (PG_KWE | PG_UWE)) { 1957 if (opte & (PG_KWE | PG_UWE)) {
1961 atomic_store_relaxed(pv->pv_pte, 1958 atomic_store_relaxed(pv->pv_pte,
1962 opte & ~(PG_KWE | PG_UWE)); 1959 opte & ~(PG_KWE | PG_UWE));
1963 pmap_tlb_shootdown_pv(pv->pv_pmap, pv->pv_va, 1960 pmap_tlb_shootdown_pv(pv->pv_pmap, pv->pv_va,
1964 opte, &tlbctx); 1961 opte, &tlbctx);
1965 } 1962 }
1966 PMAP_UNLOCK(pv->pv_pmap); 1963 PMAP_UNLOCK(pv->pv_pmap);
1967 } 1964 }
1968 mutex_exit(lock); 1965 mutex_exit(lock);
1969 PMAP_HEAD_TO_MAP_UNLOCK(); 1966 PMAP_HEAD_TO_MAP_UNLOCK();
1970 pmap_tlb_shootnow(&tlbctx); 1967 pmap_tlb_shootnow(&tlbctx);
1971 TLB_COUNT(reason_page_protect_read); 1968 TLB_COUNT(reason_page_protect_read);
1972 return; 1969 return;
1973 1970
1974 /* remove_all */ 1971 /* remove_all */
1975 default: 1972 default:
1976 break; 1973 break;
1977 } 1974 }
1978 1975
1979 PMAP_HEAD_TO_MAP_LOCK(); 1976 PMAP_HEAD_TO_MAP_LOCK();
1980 lock = pmap_pvh_lock(pg); 1977 lock = pmap_pvh_lock(pg);
1981 mutex_enter(lock); 1978 mutex_enter(lock);
1982 for (pv = VM_MDPAGE_PVS(pg); pv != NULL; pv = nextpv) { 1979 for (pv = VM_MDPAGE_PVS(pg); pv != NULL; pv = nextpv) {
1983 pt_entry_t pte_bits; 1980 pt_entry_t pte_bits;
1984 pmap_t pmap; 1981 pmap_t pmap;
1985 vaddr_t va; 1982 vaddr_t va;
1986 1983
1987 nextpv = pv->pv_next; 1984 nextpv = pv->pv_next;
1988 1985
1989 PMAP_LOCK(pv->pv_pmap); 1986 PMAP_LOCK(pv->pv_pmap);
1990 pmap = pv->pv_pmap; 1987 pmap = pv->pv_pmap;
1991 va = pv->pv_va; 1988 va = pv->pv_va;
1992 pte_bits = pmap_remove_mapping(pmap, va, pv->pv_pte, 1989 pte_bits = pmap_remove_mapping(pmap, va, pv->pv_pte,
1993 false, NULL, &tlbctx); 1990 false, NULL, &tlbctx);
1994 pmap_tlb_shootdown_pv(pmap, va, pte_bits, &tlbctx); 1991 pmap_tlb_shootdown_pv(pmap, va, pte_bits, &tlbctx);
1995 PMAP_UNLOCK(pv->pv_pmap); 1992 PMAP_UNLOCK(pv->pv_pmap);
1996 } 1993 }
1997 mutex_exit(lock); 1994 mutex_exit(lock);
1998 PMAP_HEAD_TO_MAP_UNLOCK(); 1995 PMAP_HEAD_TO_MAP_UNLOCK();
1999 pmap_tlb_shootnow(&tlbctx); 1996 pmap_tlb_shootnow(&tlbctx);
2000 pmap_tlb_context_drain(&tlbctx); 1997 pmap_tlb_context_drain(&tlbctx);
2001 TLB_COUNT(reason_page_protect_none); 1998 TLB_COUNT(reason_page_protect_none);
2002} 1999}
2003 2000
2004/* 2001/*
2005 * pmap_protect: [ INTERFACE ] 2002 * pmap_protect: [ INTERFACE ]
2006 * 2003 *
2007 * Set the physical protection on the specified range of this map 2004 * Set the physical protection on the specified range of this map
2008 * as requested. 2005 * as requested.
2009 */ 2006 */
2010void 2007void
2011pmap_protect(pmap_t pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot) 2008pmap_protect(pmap_t pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot)
2012{ 2009{
2013 pt_entry_t *l1pte, *l2pte, *l3pte, opte; 2010 pt_entry_t *l1pte, *l2pte, *l3pte, opte;
2014 vaddr_t l1eva, l2eva; 2011 vaddr_t l1eva, l2eva;
2015 struct pmap_tlb_context tlbctx; 2012 struct pmap_tlb_context tlbctx;
2016 2013
2017#ifdef DEBUG 2014#ifdef DEBUG
2018 if (pmapdebug & (PDB_FOLLOW|PDB_PROTECT)) 2015 if (pmapdebug & (PDB_FOLLOW|PDB_PROTECT))
2019 printf("pmap_protect(%p, %lx, %lx, %x)\n", 2016 printf("pmap_protect(%p, %lx, %lx, %x)\n",
2020 pmap, sva, eva, prot); 2017 pmap, sva, eva, prot);
2021#endif 2018#endif
2022 2019
2023 pmap_tlb_context_init(&tlbctx, 0); 2020 pmap_tlb_context_init(&tlbctx, 0);
2024 2021
2025 if ((prot & VM_PROT_READ) == VM_PROT_NONE) { 2022 if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
2026 pmap_remove_internal(pmap, sva, eva, &tlbctx); 2023 pmap_remove_internal(pmap, sva, eva, &tlbctx);
2027 return; 2024 return;
2028 } 2025 }
2029 2026
2030 const pt_entry_t bits = pte_prot(pmap, prot); 2027 const pt_entry_t bits = pte_prot(pmap, prot);
2031 pt_entry_t * const lev1map = pmap_lev1map(pmap); 2028 pt_entry_t * const lev1map = pmap_lev1map(pmap);
2032 2029
2033 PMAP_LOCK(pmap); 2030 PMAP_LOCK(pmap);
2034 2031
2035 l1pte = pmap_l1pte(lev1map, sva); 2032 l1pte = pmap_l1pte(lev1map, sva);
2036 for (; sva < eva; sva = l1eva, l1pte++) { 2033 for (; sva < eva; sva = l1eva, l1pte++) {
2037 l1eva = alpha_trunc_l1seg(sva) + ALPHA_L1SEG_SIZE; 2034 l1eva = alpha_trunc_l1seg(sva) + ALPHA_L1SEG_SIZE;
2038 if (pmap_pte_v(l1pte)) { 2035 if (pmap_pte_v(l1pte)) {
2039 l2pte = pmap_l2pte(lev1map, sva, l1pte); 2036 l2pte = pmap_l2pte(lev1map, sva, l1pte);
2040 for (; sva < l1eva && sva < eva; sva = l2eva, l2pte++) { 2037 for (; sva < l1eva && sva < eva; sva = l2eva, l2pte++) {
2041 l2eva = 2038 l2eva =
2042 alpha_trunc_l2seg(sva) + ALPHA_L2SEG_SIZE; 2039 alpha_trunc_l2seg(sva) + ALPHA_L2SEG_SIZE;
2043 if (pmap_pte_v(l2pte)) { 2040 if (pmap_pte_v(l2pte)) {
2044 l3pte = pmap_l3pte(lev1map, sva, l2pte); 2041 l3pte = pmap_l3pte(lev1map, sva, l2pte);
2045 for (; sva < l2eva && sva < eva; 2042 for (; sva < l2eva && sva < eva;
2046 sva += PAGE_SIZE, l3pte++) { 2043 sva += PAGE_SIZE, l3pte++) {
2047 if (pmap_pte_v(l3pte) && 2044 if (pmap_pte_v(l3pte) &&
2048 pmap_pte_prot_chg(l3pte, 2045 pmap_pte_prot_chg(l3pte,
2049 bits)) { 2046 bits)) {
2050 opte = atomic_load_relaxed(l3pte); 2047 opte = atomic_load_relaxed(l3pte);
2051 pmap_pte_set_prot(l3pte, 2048 pmap_pte_set_prot(l3pte,
2052 bits); 2049 bits);
2053 pmap_tlb_shootdown(pmap, 2050 pmap_tlb_shootdown(pmap,
2054 sva, opte, &tlbctx); 2051 sva, opte, &tlbctx);
2055 } 2052 }
2056 } 2053 }
2057 } 2054 }
2058 } 2055 }
2059 } 2056 }
2060 } 2057 }
2061 2058
2062 PMAP_UNLOCK(pmap); 2059 PMAP_UNLOCK(pmap);
2063 pmap_tlb_shootnow(&tlbctx); 2060 pmap_tlb_shootnow(&tlbctx);
2064 TLB_COUNT(reason_protect); 2061 TLB_COUNT(reason_protect);
2065} 2062}
2066 2063
2067/* 2064/*
2068 * pmap_enter_tlb_shootdown: 2065 * pmap_enter_tlb_shootdown:
2069 * 2066 *
2070 * Carry out a TLB shootdown on behalf of a pmap_enter() 2067 * Carry out a TLB shootdown on behalf of a pmap_enter()
2071 * or a pmap_kenter_pa(). This is factored out separately 2068 * or a pmap_kenter_pa(). This is factored out separately
2072 * because we expect it to be not a common case. 2069 * because we expect it to be not a common case.
2073 */ 2070 */
2074static void __noinline 2071static void __noinline
2075pmap_enter_tlb_shootdown(pmap_t const pmap, vaddr_t const va, 2072pmap_enter_tlb_shootdown(pmap_t const pmap, vaddr_t const va,
2076 pt_entry_t const pte_bits, bool locked) 2073 pt_entry_t const pte_bits, bool locked)
2077{ 2074{
2078 struct pmap_tlb_context tlbctx; 2075 struct pmap_tlb_context tlbctx;
2079 2076
2080 pmap_tlb_context_init(&tlbctx, 0); 2077 pmap_tlb_context_init(&tlbctx, 0);
2081 pmap_tlb_shootdown(pmap, va, pte_bits, &tlbctx); 2078 pmap_tlb_shootdown(pmap, va, pte_bits, &tlbctx);
2082 if (locked) { 2079 if (locked) {
2083 PMAP_UNLOCK(pmap); 2080 PMAP_UNLOCK(pmap);
2084 } 2081 }
2085 pmap_tlb_shootnow(&tlbctx); 2082 pmap_tlb_shootnow(&tlbctx);
2086} 2083}
2087 2084
2088/* 2085/*
2089 * pmap_enter_l2pt_delref: 2086 * pmap_enter_l2pt_delref:
2090 * 2087 *
2091 * Release a reference on an L2 PT page for pmap_enter(). 2088 * Release a reference on an L2 PT page for pmap_enter().
2092 * This is factored out separately becacause we expect it 2089 * This is factored out separately becacause we expect it
2093 * to be a rare case. 2090 * to be a rare case.
2094 */ 2091 */
2095static void __noinline 2092static void __noinline
2096pmap_enter_l2pt_delref(pmap_t const pmap, pt_entry_t * const l1pte, 2093pmap_enter_l2pt_delref(pmap_t const pmap, pt_entry_t * const l1pte,
2097 pt_entry_t * const l2pte) 2094 pt_entry_t * const l2pte)
2098{ 2095{
2099 struct pmap_tlb_context tlbctx; 2096 struct pmap_tlb_context tlbctx;
2100 2097
2101 /* 2098 /*
2102 * PALcode may have tried to service a TLB miss with 2099 * PALcode may have tried to service a TLB miss with
2103 * this L2 PTE, so we need to make sure we don't actully 2100 * this L2 PTE, so we need to make sure we don't actully
2104 * free the PT page untl we've shot down any TLB entries 2101 * free the PT page untl we've shot down any TLB entries
2105 * for this VPT index. 2102 * for this VPT index.
2106 */ 2103 */
2107 2104
2108 pmap_tlb_context_init(&tlbctx, 0); 2105 pmap_tlb_context_init(&tlbctx, 0);
2109 pmap_l2pt_delref(pmap, l1pte, l2pte, &tlbctx); 2106 pmap_l2pt_delref(pmap, l1pte, l2pte, &tlbctx);
2110 PMAP_UNLOCK(pmap); 2107 PMAP_UNLOCK(pmap);
2111 pmap_tlb_shootnow(&tlbctx); 2108 pmap_tlb_shootnow(&tlbctx);
2112 pmap_tlb_context_drain(&tlbctx); 2109 pmap_tlb_context_drain(&tlbctx);
2113 TLB_COUNT(reason_enter_l2pt_delref); 2110 TLB_COUNT(reason_enter_l2pt_delref);
2114} 2111}
2115 2112
2116/* 2113/*
2117 * pmap_enter_l3pt_delref: 2114 * pmap_enter_l3pt_delref:
2118 * 2115 *
2119 * Release a reference on an L3 PT page for pmap_enter(). 2116 * Release a reference on an L3 PT page for pmap_enter().
2120 * This is factored out separately becacause we expect it 2117 * This is factored out separately becacause we expect it
2121 * to be a rare case. 2118 * to be a rare case.
2122 */ 2119 */
2123static void __noinline 2120static void __noinline
2124pmap_enter_l3pt_delref(pmap_t const pmap, vaddr_t const va, 2121pmap_enter_l3pt_delref(pmap_t const pmap, vaddr_t const va,
2125 pt_entry_t * const pte) 2122 pt_entry_t * const pte)
2126{ 2123{
2127 struct pmap_tlb_context tlbctx; 2124 struct pmap_tlb_context tlbctx;
2128 2125
2129 /* 2126 /*
2130 * PALcode may have tried to service a TLB miss with 2127 * PALcode may have tried to service a TLB miss with
2131 * this PTE, so we need to make sure we don't actully 2128 * this PTE, so we need to make sure we don't actully
2132 * free the PT page untl we've shot down any TLB entries 2129 * free the PT page untl we've shot down any TLB entries
2133 * for this VPT index. 2130 * for this VPT index.
2134 */ 2131 */
2135 2132
2136 pmap_tlb_context_init(&tlbctx, 0); 2133 pmap_tlb_context_init(&tlbctx, 0);
2137 pmap_l3pt_delref(pmap, va, pte, &tlbctx); 2134 pmap_l3pt_delref(pmap, va, pte, &tlbctx);
2138 PMAP_UNLOCK(pmap); 2135 PMAP_UNLOCK(pmap);
2139 pmap_tlb_shootnow(&tlbctx); 2136 pmap_tlb_shootnow(&tlbctx);
2140 pmap_tlb_context_drain(&tlbctx); 2137 pmap_tlb_context_drain(&tlbctx);
2141 TLB_COUNT(reason_enter_l3pt_delref); 2138 TLB_COUNT(reason_enter_l3pt_delref);
2142} 2139}
2143 2140
2144/* 2141/*
2145 * pmap_enter: [ INTERFACE ] 2142 * pmap_enter: [ INTERFACE ]
2146 * 2143 *
2147 * Insert the given physical page (p) at 2144 * Insert the given physical page (p) at
2148 * the specified virtual address (v) in the 2145 * the specified virtual address (v) in the
2149 * target physical map with the protection requested. 2146 * target physical map with the protection requested.
2150 * 2147 *
2151 * If specified, the page will be wired down, meaning 2148 * If specified, the page will be wired down, meaning
2152 * that the related pte can not be reclaimed. 2149 * that the related pte can not be reclaimed.
2153 * 2150 *
2154 * Note: This is the only routine which MAY NOT lazy-evaluate 2151 * Note: This is the only routine which MAY NOT lazy-evaluate
2155 * or lose information. That is, this routine must actually 2152 * or lose information. That is, this routine must actually
2156 * insert this page into the given map NOW. 2153 * insert this page into the given map NOW.
2157 */ 2154 */
2158int 2155int
2159pmap_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags) 2156pmap_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags)
2160{ 2157{
2161 pt_entry_t *pte, npte, opte; 2158 pt_entry_t *pte, npte, opte;
2162 pv_entry_t opv = NULL; 2159 pv_entry_t opv = NULL;
2163 paddr_t opa; 2160 paddr_t opa;
2164 bool tflush = false; 2161 bool tflush = false;
2165 int error = 0; 2162 int error = 0;
2166 kmutex_t *lock; 2163 kmutex_t *lock;
2167 2164
2168#ifdef DEBUG 2165#ifdef DEBUG
2169 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER)) 2166 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER))
2170 printf("pmap_enter(%p, %lx, %lx, %x, %x)\n", 2167 printf("pmap_enter(%p, %lx, %lx, %x, %x)\n",
2171 pmap, va, pa, prot, flags); 2168 pmap, va, pa, prot, flags);
2172#endif 2169#endif
2173 struct vm_page * const pg = PHYS_TO_VM_PAGE(pa); 2170 struct vm_page * const pg = PHYS_TO_VM_PAGE(pa);
2174 const bool wired = (flags & PMAP_WIRED) != 0; 2171 const bool wired = (flags & PMAP_WIRED) != 0;
2175 2172
2176 PMAP_MAP_TO_HEAD_LOCK(); 2173 PMAP_MAP_TO_HEAD_LOCK();
2177 PMAP_LOCK(pmap); 2174 PMAP_LOCK(pmap);
2178 2175
2179 if (pmap == pmap_kernel()) { 2176 if (pmap == pmap_kernel()) {
2180 KASSERT(va >= VM_MIN_KERNEL_ADDRESS); 2177 KASSERT(va >= VM_MIN_KERNEL_ADDRESS);
2181 pte = PMAP_KERNEL_PTE(va); 2178 pte = PMAP_KERNEL_PTE(va);
2182 } else { 2179 } else {
2183 pt_entry_t *l1pte, *l2pte; 2180 pt_entry_t *l1pte, *l2pte;
2184 pt_entry_t * const lev1map = pmap_lev1map(pmap); 2181 pt_entry_t * const lev1map = pmap_lev1map(pmap);
2185 2182
2186 KASSERT(va < VM_MAXUSER_ADDRESS); 2183 KASSERT(va < VM_MAXUSER_ADDRESS);
2187 KASSERT(lev1map != kernel_lev1map); 2184 KASSERT(lev1map != kernel_lev1map);
2188 2185
2189 /* 2186 /*
2190 * Check to see if the level 1 PTE is valid, and 2187 * Check to see if the level 1 PTE is valid, and
2191 * allocate a new level 2 page table page if it's not. 2188 * allocate a new level 2 page table page if it's not.
2192 * A reference will be added to the level 2 table when 2189 * A reference will be added to the level 2 table when
2193 * the level 3 table is created. 2190 * the level 3 table is created.
2194 */ 2191 */
2195 l1pte = pmap_l1pte(lev1map, va); 2192 l1pte = pmap_l1pte(lev1map, va);
2196 if (pmap_pte_v(l1pte) == 0) { 2193 if (pmap_pte_v(l1pte) == 0) {
2197 pmap_physpage_addref(l1pte); 2194 pmap_physpage_addref(l1pte);
2198 error = pmap_ptpage_alloc(pmap, l1pte, PGU_L2PT); 2195 error = pmap_ptpage_alloc(pmap, l1pte, PGU_L2PT);
2199 if (error) { 2196 if (error) {
2200 pmap_l1pt_delref(pmap, l1pte); 2197 pmap_l1pt_delref(pmap, l1pte);
2201 if (flags & PMAP_CANFAIL) 2198 if (flags & PMAP_CANFAIL)
2202 goto out; 2199 goto out;
2203 panic("pmap_enter: unable to create L2 PT " 2200 panic("pmap_enter: unable to create L2 PT "
2204 "page"); 2201 "page");
2205 } 2202 }
2206#ifdef DEBUG 2203#ifdef DEBUG
2207 if (pmapdebug & PDB_PTPAGE) 2204 if (pmapdebug & PDB_PTPAGE)
2208 printf("pmap_enter: new level 2 table at " 2205 printf("pmap_enter: new level 2 table at "
2209 "0x%lx\n", pmap_pte_pa(l1pte)); 2206 "0x%lx\n", pmap_pte_pa(l1pte));
2210#endif 2207#endif
2211 } 2208 }
2212 2209
2213 /* 2210 /*
2214 * Check to see if the level 2 PTE is valid, and 2211 * Check to see if the level 2 PTE is valid, and
2215 * allocate a new level 3 page table page if it's not. 2212 * allocate a new level 3 page table page if it's not.
2216 * A reference will be added to the level 3 table when 2213 * A reference will be added to the level 3 table when
2217 * the mapping is validated. 2214 * the mapping is validated.
2218 */ 2215 */
2219 l2pte = pmap_l2pte(lev1map, va, l1pte); 2216 l2pte = pmap_l2pte(lev1map, va, l1pte);
2220 if (pmap_pte_v(l2pte) == 0) { 2217 if (pmap_pte_v(l2pte) == 0) {
2221 pmap_physpage_addref(l2pte); 2218 pmap_physpage_addref(l2pte);
2222 error = pmap_ptpage_alloc(pmap, l2pte, PGU_L3PT); 2219 error = pmap_ptpage_alloc(pmap, l2pte, PGU_L3PT);
2223 if (error) { 2220 if (error) {
2224 /* unlocks pmap */ 2221 /* unlocks pmap */
2225 pmap_enter_l2pt_delref(pmap, l1pte, l2pte); 2222 pmap_enter_l2pt_delref(pmap, l1pte, l2pte);
2226 if (flags & PMAP_CANFAIL) { 2223 if (flags & PMAP_CANFAIL) {
2227 PMAP_LOCK(pmap); 2224 PMAP_LOCK(pmap);
2228 goto out; 2225 goto out;
2229 } 2226 }
2230 panic("pmap_enter: unable to create L3 PT " 2227 panic("pmap_enter: unable to create L3 PT "
2231 "page"); 2228 "page");
2232 } 2229 }
2233#ifdef DEBUG 2230#ifdef DEBUG
2234 if (pmapdebug & PDB_PTPAGE) 2231 if (pmapdebug & PDB_PTPAGE)
2235 printf("pmap_enter: new level 3 table at " 2232 printf("pmap_enter: new level 3 table at "
2236 "0x%lx\n", pmap_pte_pa(l2pte)); 2233 "0x%lx\n", pmap_pte_pa(l2pte));
2237#endif 2234#endif
2238 } 2235 }
2239 2236
2240 /* 2237 /*
2241 * Get the PTE that will map the page. 2238 * Get the PTE that will map the page.
2242 */ 2239 */
2243 pte = pmap_l3pte(lev1map, va, l2pte); 2240 pte = pmap_l3pte(lev1map, va, l2pte);
2244 } 2241 }
2245 2242
2246 /* Remember all of the old PTE; used for TBI check later. */ 2243 /* Remember all of the old PTE; used for TBI check later. */
2247 opte = atomic_load_relaxed(pte); 2244 opte = atomic_load_relaxed(pte);
2248 2245
2249 /* 2246 /*
2250 * Check to see if the old mapping is valid. If not, validate the 2247 * Check to see if the old mapping is valid. If not, validate the
2251 * new one immediately. 2248 * new one immediately.
2252 */ 2249 */
2253 if ((opte & PG_V) == 0) { 2250 if ((opte & PG_V) == 0) {
2254 /* No TLB invalidatons needed for new mappings. */ 2251 /* No TLB invalidatons needed for new mappings. */
2255 2252
2256 if (pmap != pmap_kernel()) { 2253 if (pmap != pmap_kernel()) {
2257 /* 2254 /*
2258 * New mappings gain a reference on the level 3 2255 * New mappings gain a reference on the level 3
2259 * table. 2256 * table.
2260 */ 2257 */
2261 pmap_physpage_addref(pte); 2258 pmap_physpage_addref(pte);
2262 } 2259 }
2263 goto validate_enterpv; 2260 goto validate_enterpv;
2264 } 2261 }
2265 2262
2266 opa = pmap_pte_pa(pte); 2263 opa = pmap_pte_pa(pte);
2267 2264
2268 if (opa == pa) { 2265 if (opa == pa) {
2269 /* 2266 /*
2270 * Mapping has not changed; must be a protection or 2267 * Mapping has not changed; must be a protection or
2271 * wiring change. 2268 * wiring change.
2272 */ 2269 */
2273 if (pmap_pte_w_chg(pte, wired ? PG_WIRED : 0)) { 2270 if (pmap_pte_w_chg(pte, wired ? PG_WIRED : 0)) {
2274#ifdef DEBUG 2271#ifdef DEBUG
2275 if (pmapdebug & PDB_ENTER) 2272 if (pmapdebug & PDB_ENTER)
2276 printf("pmap_enter: wiring change -> %d\n", 2273 printf("pmap_enter: wiring change -> %d\n",
2277 wired); 2274 wired);
2278#endif 2275#endif
2279 /* Adjust the wiring count. */ 2276 /* Adjust the wiring count. */
2280 if (wired) 2277 if (wired)
2281 PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1); 2278 PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1);
2282 else 2279 else
2283 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1); 2280 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1);
2284 } 2281 }
2285 2282
2286 /* Set the PTE. */ 2283 /* Set the PTE. */
2287 goto validate; 2284 goto validate;
2288 } 2285 }
2289 2286
2290 /* 2287 /*
2291 * The mapping has changed. We need to invalidate the 2288 * The mapping has changed. We need to invalidate the
2292 * old mapping before creating the new one. 2289 * old mapping before creating the new one.
2293 */ 2290 */
2294#ifdef DEBUG 2291#ifdef DEBUG
2295 if (pmapdebug & PDB_ENTER) 2292 if (pmapdebug & PDB_ENTER)
2296 printf("pmap_enter: removing old mapping 0x%lx\n", va); 2293 printf("pmap_enter: removing old mapping 0x%lx\n", va);
2297#endif 2294#endif
2298 if (pmap != pmap_kernel()) { 2295 if (pmap != pmap_kernel()) {
2299 /* 2296 /*
2300 * Gain an extra reference on the level 3 table. 2297 * Gain an extra reference on the level 3 table.
2301 * pmap_remove_mapping() will delete a reference, 2298 * pmap_remove_mapping() will delete a reference,
2302 * and we don't want the table to be erroneously 2299 * and we don't want the table to be erroneously
2303 * freed. 2300 * freed.
2304 */ 2301 */
2305 pmap_physpage_addref(pte); 2302 pmap_physpage_addref(pte);
2306 } 2303 }
2307 /* Already have the bits from opte above. */ 2304 /* Already have the bits from opte above. */
2308 (void) pmap_remove_mapping(pmap, va, pte, true, &opv, NULL); 2305 (void) pmap_remove_mapping(pmap, va, pte, true, &opv, NULL);
2309 2306
2310 validate_enterpv: 2307 validate_enterpv:
2311 /* Enter the mapping into the pv_table if appropriate. */ 2308 /* Enter the mapping into the pv_table if appropriate. */
2312 if (pg != NULL) { 2309 if (pg != NULL) {
2313 error = pmap_pv_enter(pmap, pg, va, pte, true, opv); 2310 error = pmap_pv_enter(pmap, pg, va, pte, true, opv);
2314 if (error) { 2311 if (error) {
2315 /* This can only fail if opv == NULL */ 2312 /* This can only fail if opv == NULL */
2316 KASSERT(opv == NULL); 2313 KASSERT(opv == NULL);
2317 2314
2318 /* unlocks pmap */ 2315 /* unlocks pmap */
2319 pmap_enter_l3pt_delref(pmap, va, pte); 2316 pmap_enter_l3pt_delref(pmap, va, pte);
2320 if (flags & PMAP_CANFAIL) { 2317 if (flags & PMAP_CANFAIL) {
2321 PMAP_LOCK(pmap); 2318 PMAP_LOCK(pmap);
2322 goto out; 2319 goto out;
2323 } 2320 }
2324 panic("pmap_enter: unable to enter mapping in PV " 2321 panic("pmap_enter: unable to enter mapping in PV "
2325 "table"); 2322 "table");
2326 } 2323 }
2327 opv = NULL; 2324 opv = NULL;
2328 } 2325 }
2329 2326
2330 /* Increment counters. */ 2327 /* Increment counters. */
2331 PMAP_STAT_INCR(pmap->pm_stats.resident_count, 1); 2328 PMAP_STAT_INCR(pmap->pm_stats.resident_count, 1);
2332 if (wired) 2329 if (wired)
2333 PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1); 2330 PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1);
2334 2331
2335 validate: 2332 validate:
2336 /* Build the new PTE. */ 2333 /* Build the new PTE. */
2337 npte = ((pa >> PGSHIFT) << PG_SHIFT) | pte_prot(pmap, prot) | PG_V; 2334 npte = ((pa >> PGSHIFT) << PG_SHIFT) | pte_prot(pmap, prot) | PG_V;
2338 if (pg != NULL) { 2335 if (pg != NULL) {
2339 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 2336 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
2340 uintptr_t attrs = 0; 2337 uintptr_t attrs = 0;
2341 2338
2342 KASSERT(((flags & VM_PROT_ALL) & ~prot) == 0); 2339 KASSERT(((flags & VM_PROT_ALL) & ~prot) == 0);
2343 2340
2344 if (flags & VM_PROT_WRITE) 2341 if (flags & VM_PROT_WRITE)
2345 attrs |= (PGA_REFERENCED|PGA_MODIFIED); 2342 attrs |= (PGA_REFERENCED|PGA_MODIFIED);
2346 else if (flags & VM_PROT_ALL) 2343 else if (flags & VM_PROT_ALL)
2347 attrs |= PGA_REFERENCED; 2344 attrs |= PGA_REFERENCED;
2348 2345
2349 lock = pmap_pvh_lock(pg); 2346 lock = pmap_pvh_lock(pg);
2350 mutex_enter(lock); 2347 mutex_enter(lock);
2351 md->pvh_listx |= attrs; 2348 md->pvh_listx |= attrs;
2352 mutex_exit(lock); 2349 mutex_exit(lock);
2353 2350
2354 /* Set up referenced/modified emulation for new mapping. */ 2351 /* Set up referenced/modified emulation for new mapping. */
2355 if ((attrs & PGA_REFERENCED) == 0) 2352 if ((attrs & PGA_REFERENCED) == 0)
2356 npte |= PG_FOR | PG_FOW | PG_FOE; 2353 npte |= PG_FOR | PG_FOW | PG_FOE;
2357 else if ((attrs & PGA_MODIFIED) == 0) 2354 else if ((attrs & PGA_MODIFIED) == 0)
2358 npte |= PG_FOW; 2355 npte |= PG_FOW;
2359 2356
2360 /* 2357 /*
2361 * Mapping was entered on PV list. 2358 * Mapping was entered on PV list.
2362 */ 2359 */
2363 npte |= PG_PVLIST; 2360 npte |= PG_PVLIST;
2364 } 2361 }
2365 if (wired) 2362 if (wired)
2366 npte |= PG_WIRED; 2363 npte |= PG_WIRED;
2367#ifdef DEBUG 2364#ifdef DEBUG
2368 if (pmapdebug & PDB_ENTER) 2365 if (pmapdebug & PDB_ENTER)
2369 printf("pmap_enter: new pte = 0x%lx\n", npte); 2366 printf("pmap_enter: new pte = 0x%lx\n", npte);
2370#endif 2367#endif
2371 2368
2372 /* 2369 /*
2373 * If the HW / PALcode portion of the new PTE is the same as the 2370 * If the HW / PALcode portion of the new PTE is the same as the
2374 * old PTE, no TBI is necessary. 2371 * old PTE, no TBI is necessary.
2375 */ 2372 */
2376 if (opte & PG_V) { 2373 if (opte & PG_V) {
2377 tflush = PG_PALCODE(opte) != PG_PALCODE(npte); 2374 tflush = PG_PALCODE(opte) != PG_PALCODE(npte);
2378 } 2375 }
2379 2376
2380 /* Set the new PTE. */ 2377 /* Set the new PTE. */
2381 atomic_store_relaxed(pte, npte); 2378 atomic_store_relaxed(pte, npte);
2382 2379
2383out: 2380out:
2384 PMAP_MAP_TO_HEAD_UNLOCK(); 2381 PMAP_MAP_TO_HEAD_UNLOCK();
2385 2382
2386 /* 2383 /*
2387 * Invalidate the TLB entry for this VA and any appropriate 2384 * Invalidate the TLB entry for this VA and any appropriate
2388 * caches. 2385 * caches.
2389 */ 2386 */
2390 if (tflush) { 2387 if (tflush) {
2391 /* unlocks pmap */ 2388 /* unlocks pmap */
2392 pmap_enter_tlb_shootdown(pmap, va, opte, true); 2389 pmap_enter_tlb_shootdown(pmap, va, opte, true);
2393 if (pmap == pmap_kernel()) { 2390 if (pmap == pmap_kernel()) {
2394 TLB_COUNT(reason_enter_kernel); 2391 TLB_COUNT(reason_enter_kernel);
2395 } else { 2392 } else {
2396 TLB_COUNT(reason_enter_user); 2393 TLB_COUNT(reason_enter_user);
2397 } 2394 }
2398 } else { 2395 } else {
2399 PMAP_UNLOCK(pmap); 2396 PMAP_UNLOCK(pmap);
2400 } 2397 }
2401 2398
2402 if (opv) 2399 if (opv)
2403 pmap_pv_free(opv); 2400 pmap_pv_free(opv);
2404 2401
2405 return error; 2402 return error;
2406} 2403}
2407 2404
2408/* 2405/*
2409 * pmap_kenter_pa: [ INTERFACE ] 2406 * pmap_kenter_pa: [ INTERFACE ]
2410 * 2407 *
2411 * Enter a va -> pa mapping into the kernel pmap without any 2408 * Enter a va -> pa mapping into the kernel pmap without any
2412 * physical->virtual tracking. 2409 * physical->virtual tracking.
2413 * 2410 *
2414 * Note: no locking is necessary in this function. 2411 * Note: no locking is necessary in this function.
2415 */ 2412 */
2416void 2413void
2417pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags) 2414pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags)
2418{ 2415{
2419 pmap_t const pmap = pmap_kernel(); 2416 pmap_t const pmap = pmap_kernel();
2420 2417
2421#ifdef DEBUG 2418#ifdef DEBUG
2422 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER)) 2419 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER))
2423 printf("pmap_kenter_pa(%lx, %lx, %x)\n", 2420 printf("pmap_kenter_pa(%lx, %lx, %x)\n",
2424 va, pa, prot); 2421 va, pa, prot);
2425#endif 2422#endif
2426 2423
2427 KASSERT(va >= VM_MIN_KERNEL_ADDRESS); 2424 KASSERT(va >= VM_MIN_KERNEL_ADDRESS);
2428 2425
2429 pt_entry_t * const pte = PMAP_KERNEL_PTE(va); 2426 pt_entry_t * const pte = PMAP_KERNEL_PTE(va);
2430 2427
2431 /* Build the new PTE. */ 2428 /* Build the new PTE. */
2432 const pt_entry_t npte = 2429 const pt_entry_t npte =
2433 ((pa >> PGSHIFT) << PG_SHIFT) | pte_prot(pmap_kernel(), prot) | 2430 ((pa >> PGSHIFT) << PG_SHIFT) | pte_prot(pmap_kernel(), prot) |
2434 PG_V | PG_WIRED; 2431 PG_V | PG_WIRED;
2435 2432
2436 /* Set the new PTE. */ 2433 /* Set the new PTE. */
2437 const pt_entry_t opte = atomic_load_relaxed(pte); 2434 const pt_entry_t opte = atomic_load_relaxed(pte);
2438 atomic_store_relaxed(pte, npte); 2435 atomic_store_relaxed(pte, npte);
2439 2436
2440 PMAP_STAT_INCR(pmap->pm_stats.resident_count, 1); 2437 PMAP_STAT_INCR(pmap->pm_stats.resident_count, 1);
2441 PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1); 2438 PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1);
2442 2439
2443 /* 2440 /*
2444 * There should not have been anything here, previously, 2441 * There should not have been anything here, previously,
2445 * so we can skip TLB shootdowns, etc. in the common case. 2442 * so we can skip TLB shootdowns, etc. in the common case.
2446 */ 2443 */
2447 if (__predict_false(opte & PG_V)) { 2444 if (__predict_false(opte & PG_V)) {
2448 const pt_entry_t diff = npte ^ opte; 2445 const pt_entry_t diff = npte ^ opte;
2449 2446
2450 printf_nolog("%s: mapping already present\n", __func__); 2447 printf_nolog("%s: mapping already present\n", __func__);
2451 PMAP_STAT_DECR(pmap->pm_stats.resident_count, 1); 2448 PMAP_STAT_DECR(pmap->pm_stats.resident_count, 1);
2452 if (diff & PG_WIRED) 2449 if (diff & PG_WIRED)
2453 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1); 2450 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1);
2454 /* XXX Can't handle this case. */ 2451 /* XXX Can't handle this case. */
2455 if (diff & PG_PVLIST) 2452 if (diff & PG_PVLIST)
2456 panic("pmap_kenter_pa: old mapping was managed"); 2453 panic("pmap_kenter_pa: old mapping was managed");
2457 2454
2458 pmap_enter_tlb_shootdown(pmap_kernel(), va, opte, false); 2455 pmap_enter_tlb_shootdown(pmap_kernel(), va, opte, false);
2459 TLB_COUNT(reason_kenter); 2456 TLB_COUNT(reason_kenter);
2460 } 2457 }
2461} 2458}
2462 2459
2463/* 2460/*
2464 * pmap_kremove: [ INTERFACE ] 2461 * pmap_kremove: [ INTERFACE ]
2465 * 2462 *
2466 * Remove a mapping entered with pmap_kenter_pa() starting at va, 2463 * Remove a mapping entered with pmap_kenter_pa() starting at va,
2467 * for size bytes (assumed to be page rounded). 2464 * for size bytes (assumed to be page rounded).
2468 */ 2465 */
2469void 2466void
2470pmap_kremove(vaddr_t va, vsize_t size) 2467pmap_kremove(vaddr_t va, vsize_t size)
2471{ 2468{
2472 pt_entry_t *pte, opte; 2469 pt_entry_t *pte, opte;
2473 pmap_t const pmap = pmap_kernel(); 2470 pmap_t const pmap = pmap_kernel();
2474 struct pmap_tlb_context tlbctx; 2471 struct pmap_tlb_context tlbctx;
2475 int count = 0; 2472 int count = 0;
2476 2473
2477#ifdef DEBUG 2474#ifdef DEBUG
2478 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER)) 2475 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER))
2479 printf("pmap_kremove(%lx, %lx)\n", 2476 printf("pmap_kremove(%lx, %lx)\n",
2480 va, size); 2477 va, size);
2481#endif 2478#endif
2482 2479
2483 pmap_tlb_context_init(&tlbctx, 0); 2480 pmap_tlb_context_init(&tlbctx, 0);
2484 2481
2485 KASSERT(va >= VM_MIN_KERNEL_ADDRESS); 2482 KASSERT(va >= VM_MIN_KERNEL_ADDRESS);
2486 2483
2487 for (; size != 0; size -= PAGE_SIZE, va += PAGE_SIZE) { 2484 for (; size != 0; size -= PAGE_SIZE, va += PAGE_SIZE) {
2488 pte = PMAP_KERNEL_PTE(va); 2485 pte = PMAP_KERNEL_PTE(va);
2489 opte = atomic_load_relaxed(pte); 2486 opte = atomic_load_relaxed(pte);
2490 if (opte & PG_V) { 2487 if (opte & PG_V) {
2491 KASSERT((opte & PG_PVLIST) == 0); 2488 KASSERT((opte & PG_PVLIST) == 0);
2492 2489
2493 /* Zap the mapping. */ 2490 /* Zap the mapping. */
2494 atomic_store_relaxed(pte, PG_NV); 2491 atomic_store_relaxed(pte, PG_NV);
2495 pmap_tlb_shootdown(pmap, va, opte, &tlbctx); 2492 pmap_tlb_shootdown(pmap, va, opte, &tlbctx);
2496 2493
2497 count++; 2494 count++;
2498 } 2495 }
2499 } 2496 }
2500 2497
2501 /* Update stats. */ 2498 /* Update stats. */
2502 if (__predict_true(count != 0)) { 2499 if (__predict_true(count != 0)) {
2503 PMAP_STAT_DECR(pmap->pm_stats.resident_count, count); 2500 PMAP_STAT_DECR(pmap->pm_stats.resident_count, count);
2504 PMAP_STAT_DECR(pmap->pm_stats.wired_count, count); 2501 PMAP_STAT_DECR(pmap->pm_stats.wired_count, count);
2505 } 2502 }
2506 2503
2507 pmap_tlb_shootnow(&tlbctx); 2504 pmap_tlb_shootnow(&tlbctx);
2508 TLB_COUNT(reason_kremove); 2505 TLB_COUNT(reason_kremove);
2509} 2506}
2510 2507
2511/* 2508/*
2512 * pmap_unwire: [ INTERFACE ] 2509 * pmap_unwire: [ INTERFACE ]
2513 * 2510 *
2514 * Clear the wired attribute for a map/virtual-address pair. 2511 * Clear the wired attribute for a map/virtual-address pair.
2515 * 2512 *
2516 * The mapping must already exist in the pmap. 2513 * The mapping must already exist in the pmap.
2517 */ 2514 */
2518void 2515void
2519pmap_unwire(pmap_t pmap, vaddr_t va) 2516pmap_unwire(pmap_t pmap, vaddr_t va)
2520{ 2517{
2521 pt_entry_t *pte; 2518 pt_entry_t *pte;
2522 2519
2523#ifdef DEBUG 2520#ifdef DEBUG
2524 if (pmapdebug & PDB_FOLLOW) 2521 if (pmapdebug & PDB_FOLLOW)
2525 printf("pmap_unwire(%p, %lx)\n", pmap, va); 2522 printf("pmap_unwire(%p, %lx)\n", pmap, va);
2526#endif 2523#endif
2527 2524
2528 PMAP_LOCK(pmap); 2525 PMAP_LOCK(pmap);
2529 2526
2530 pte = pmap_l3pte(pmap_lev1map(pmap), va, NULL); 2527 pte = pmap_l3pte(pmap_lev1map(pmap), va, NULL);
2531 2528
2532 KASSERT(pte != NULL); 2529 KASSERT(pte != NULL);
2533 KASSERT(pmap_pte_v(pte)); 2530 KASSERT(pmap_pte_v(pte));
2534 2531
2535 /* 2532 /*
2536 * If wiring actually changed (always?) clear the wire bit and 2533 * If wiring actually changed (always?) clear the wire bit and
2537 * update the wire count. Note that wiring is not a hardware 2534 * update the wire count. Note that wiring is not a hardware
2538 * characteristic so there is no need to invalidate the TLB. 2535 * characteristic so there is no need to invalidate the TLB.
2539 */ 2536 */
2540 if (pmap_pte_w_chg(pte, 0)) { 2537 if (pmap_pte_w_chg(pte, 0)) {
2541 pmap_pte_set_w(pte, false); 2538 pmap_pte_set_w(pte, false);
2542 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1); 2539 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1);
2543 } 2540 }
2544#ifdef DEBUG 2541#ifdef DEBUG
2545 else { 2542 else {
2546 printf("pmap_unwire: wiring for pmap %p va 0x%lx " 2543 printf("pmap_unwire: wiring for pmap %p va 0x%lx "
2547 "didn't change!\n", pmap, va); 2544 "didn't change!\n", pmap, va);
2548 } 2545 }
2549#endif 2546#endif
2550 2547
2551 PMAP_UNLOCK(pmap); 2548 PMAP_UNLOCK(pmap);
2552} 2549}
2553 2550
2554/* 2551/*
2555 * pmap_extract: [ INTERFACE ] 2552 * pmap_extract: [ INTERFACE ]
2556 * 2553 *
2557 * Extract the physical address associated with the given 2554 * Extract the physical address associated with the given
2558 * pmap/virtual address pair. 2555 * pmap/virtual address pair.
2559 */ 2556 */
2560bool 2557bool
2561pmap_extract(pmap_t pmap, vaddr_t va, paddr_t *pap) 2558pmap_extract(pmap_t pmap, vaddr_t va, paddr_t *pap)
2562{ 2559{
2563 pt_entry_t *l1pte, *l2pte, *l3pte; 2560 pt_entry_t *l1pte, *l2pte, *l3pte;
2564 paddr_t pa; 2561 paddr_t pa;
2565 2562
2566#ifdef DEBUG 2563#ifdef DEBUG
2567 if (pmapdebug & PDB_FOLLOW) 2564 if (pmapdebug & PDB_FOLLOW)
2568 printf("pmap_extract(%p, %lx) -> ", pmap, va); 2565 printf("pmap_extract(%p, %lx) -> ", pmap, va);
2569#endif 2566#endif
2570 2567
2571 /* 2568 /*
2572 * Take a faster path for the kernel pmap. Avoids locking, 2569 * Take a faster path for the kernel pmap. Avoids locking,
2573 * handles K0SEG. 2570 * handles K0SEG.
2574 */ 2571 */
2575 if (__predict_true(pmap == pmap_kernel())) { 2572 if (__predict_true(pmap == pmap_kernel())) {
2576 if (__predict_true(vtophys_internal(va, pap))) { 2573 if (__predict_true(vtophys_internal(va, pap))) {
2577#ifdef DEBUG 2574#ifdef DEBUG
2578 if (pmapdebug & PDB_FOLLOW) 2575 if (pmapdebug & PDB_FOLLOW)
2579 printf("0x%lx (kernel vtophys)\n", pa); 2576 printf("0x%lx (kernel vtophys)\n", *pap);
2580#endif 2577#endif
2581 return true; 2578 return true;
2582 } 2579 }
2583#ifdef DEBUG 2580#ifdef DEBUG
2584 if (pmapdebug & PDB_FOLLOW) 2581 if (pmapdebug & PDB_FOLLOW)
2585 printf("failed (kernel vtophys)\n"); 2582 printf("failed (kernel vtophys)\n");
2586#endif 2583#endif
2587 return false; 2584 return false;
2588 } 2585 }
2589 2586
2590 pt_entry_t * const lev1map = pmap_lev1map(pmap); 2587 pt_entry_t * const lev1map = pmap_lev1map(pmap);
2591 2588
2592 PMAP_LOCK(pmap); 2589 PMAP_LOCK(pmap);
2593 2590
2594 l1pte = pmap_l1pte(lev1map, va); 2591 l1pte = pmap_l1pte(lev1map, va);
2595 if (pmap_pte_v(l1pte) == 0) 2592 if (pmap_pte_v(l1pte) == 0)
2596 goto out; 2593 goto out;
2597 2594
2598 l2pte = pmap_l2pte(lev1map, va, l1pte); 2595 l2pte = pmap_l2pte(lev1map, va, l1pte);
2599 if (pmap_pte_v(l2pte) == 0) 2596 if (pmap_pte_v(l2pte) == 0)
2600 goto out; 2597 goto out;
2601 2598
2602 l3pte = pmap_l3pte(lev1map, va, l2pte); 2599 l3pte = pmap_l3pte(lev1map, va, l2pte);
2603 if (pmap_pte_v(l3pte) == 0) 2600 if (pmap_pte_v(l3pte) == 0)
2604 goto out; 2601 goto out;
2605 2602
2606 pa = pmap_pte_pa(l3pte) | (va & PGOFSET); 2603 pa = pmap_pte_pa(l3pte) | (va & PGOFSET);
2607 PMAP_UNLOCK(pmap); 2604 PMAP_UNLOCK(pmap);
2608 if (pap != NULL) 2605 if (pap != NULL)
2609 *pap = pa; 2606 *pap = pa;
2610#ifdef DEBUG 2607#ifdef DEBUG
2611 if (pmapdebug & PDB_FOLLOW) 2608 if (pmapdebug & PDB_FOLLOW)
2612 printf("0x%lx\n", pa); 2609 printf("0x%lx\n", pa);
2613#endif 2610#endif
2614 return (true); 2611 return (true);
2615 2612
2616 out: 2613 out:
2617 PMAP_UNLOCK(pmap); 2614 PMAP_UNLOCK(pmap);
2618#ifdef DEBUG 2615#ifdef DEBUG
2619 if (pmapdebug & PDB_FOLLOW) 2616 if (pmapdebug & PDB_FOLLOW)
2620 printf("failed\n"); 2617 printf("failed\n");
2621#endif 2618#endif
2622 return (false); 2619 return (false);
2623} 2620}
2624 2621
2625/* 2622/*
2626 * pmap_copy: [ INTERFACE ] 2623 * pmap_copy: [ INTERFACE ]
2627 * 2624 *
2628 * Copy the mapping range specified by src_addr/len 2625 * Copy the mapping range specified by src_addr/len
2629 * from the source map to the range dst_addr/len 2626 * from the source map to the range dst_addr/len
2630 * in the destination map. 2627 * in the destination map.
2631 * 2628 *
2632 * This routine is only advisory and need not do anything. 2629 * This routine is only advisory and need not do anything.
2633 */ 2630 */
2634/* call deleted in <machine/pmap.h> */ 2631/* call deleted in <machine/pmap.h> */
2635 2632
2636/* 2633/*
2637 * pmap_update: [ INTERFACE ] 2634 * pmap_update: [ INTERFACE ]
2638 * 2635 *
2639 * Require that all active physical maps contain no 2636 * Require that all active physical maps contain no
2640 * incorrect entries NOW, by processing any deferred 2637 * incorrect entries NOW, by processing any deferred
2641 * pmap operations. 2638 * pmap operations.
2642 */ 2639 */
2643/* call deleted in <machine/pmap.h> */ 2640/* call deleted in <machine/pmap.h> */
2644 2641
2645/* 2642/*
2646 * pmap_activate: [ INTERFACE ] 2643 * pmap_activate: [ INTERFACE ]
2647 * 2644 *
2648 * Activate the pmap used by the specified process. This includes 2645 * Activate the pmap used by the specified process. This includes
2649 * reloading the MMU context of the current process, and marking 2646 * reloading the MMU context of the current process, and marking
2650 * the pmap in use by the processor. 2647 * the pmap in use by the processor.
2651 */ 2648 */
2652void 2649void
2653pmap_activate(struct lwp *l) 2650pmap_activate(struct lwp *l)
2654{ 2651{
2655 struct pmap * const pmap = l->l_proc->p_vmspace->vm_map.pmap; 2652 struct pmap * const pmap = l->l_proc->p_vmspace->vm_map.pmap;
2656 struct pcb * const pcb = lwp_getpcb(l); 2653 struct pcb * const pcb = lwp_getpcb(l);
2657 2654
2658#ifdef DEBUG 2655#ifdef DEBUG
2659 if (pmapdebug & PDB_FOLLOW) 2656 if (pmapdebug & PDB_FOLLOW)
2660 printf("pmap_activate(%p)\n", l); 2657 printf("pmap_activate(%p)\n", l);
2661#endif 2658#endif
2662 2659
2663 KASSERT(kpreempt_disabled()); 2660 KASSERT(kpreempt_disabled());
2664 2661
2665 struct cpu_info * const ci = curcpu(); 2662 struct cpu_info * const ci = curcpu();
2666 2663
2667 KASSERT(l == ci->ci_curlwp); 2664 KASSERT(l == ci->ci_curlwp);
2668 2665
2669 u_long const old_ptbr = pcb->pcb_hw.apcb_ptbr; 2666 u_long const old_ptbr = pcb->pcb_hw.apcb_ptbr;
2670 u_int const old_asn = pcb->pcb_hw.apcb_asn; 2667 u_int const old_asn = pcb->pcb_hw.apcb_asn;
2671 2668
2672 /* 2669 /*
2673 * We hold the activation lock to synchronize with TLB shootdown. 2670 * We hold the activation lock to synchronize with TLB shootdown.
2674 * The kernel pmap does not require those tests because shootdowns 2671 * The kernel pmap does not require those tests because shootdowns
2675 * for the kernel pmap are always sent to all CPUs. 2672 * for the kernel pmap are always sent to all CPUs.
2676 */ 2673 */
2677 if (pmap != pmap_kernel()) { 2674 if (pmap != pmap_kernel()) {
2678 PMAP_ACT_LOCK(pmap); 2675 PMAP_ACT_LOCK(pmap);
2679 pcb->pcb_hw.apcb_asn = pmap_asn_alloc(pmap, ci); 2676 pcb->pcb_hw.apcb_asn = pmap_asn_alloc(pmap, ci);
2680 atomic_or_ulong(&pmap->pm_cpus, (1UL << ci->ci_cpuid)); 2677 atomic_or_ulong(&pmap->pm_cpus, (1UL << ci->ci_cpuid));
2681 } else { 2678 } else {
2682 pcb->pcb_hw.apcb_asn = PMAP_ASN_KERNEL; 2679 pcb->pcb_hw.apcb_asn = PMAP_ASN_KERNEL;
2683 } 2680 }
2684 pcb->pcb_hw.apcb_ptbr = 2681 pcb->pcb_hw.apcb_ptbr =
2685 ALPHA_K0SEG_TO_PHYS((vaddr_t)pmap_lev1map(pmap)) >> PGSHIFT; 2682 ALPHA_K0SEG_TO_PHYS((vaddr_t)pmap_lev1map(pmap)) >> PGSHIFT;
2686 2683
2687 /* 2684 /*
2688 * Check to see if the ASN or page table base has changed; if 2685 * Check to see if the ASN or page table base has changed; if
2689 * so, switch to our own context again so that it will take 2686 * so, switch to our own context again so that it will take
2690 * effect. 2687 * effect.
2691 * 2688 *
2692 * We test ASN first because it's the most likely value to change. 2689 * We test ASN first because it's the most likely value to change.
2693 */ 2690 */
2694 if (old_asn != pcb->pcb_hw.apcb_asn || 2691 if (old_asn != pcb->pcb_hw.apcb_asn ||
2695 old_ptbr != pcb->pcb_hw.apcb_ptbr) { 2692 old_ptbr != pcb->pcb_hw.apcb_ptbr) {
2696 if (old_asn != pcb->pcb_hw.apcb_asn && 2693 if (old_asn != pcb->pcb_hw.apcb_asn &&
2697 old_ptbr != pcb->pcb_hw.apcb_ptbr) { 2694 old_ptbr != pcb->pcb_hw.apcb_ptbr) {
2698 TLB_COUNT(activate_both_change); 2695 TLB_COUNT(activate_both_change);
2699 } else if (old_asn != pcb->pcb_hw.apcb_asn) { 2696 } else if (old_asn != pcb->pcb_hw.apcb_asn) {
2700 TLB_COUNT(activate_asn_change); 2697 TLB_COUNT(activate_asn_change);
2701 } else { 2698 } else {
2702 TLB_COUNT(activate_ptbr_change); 2699 TLB_COUNT(activate_ptbr_change);
2703 } 2700 }
2704 (void) alpha_pal_swpctx((u_long)l->l_md.md_pcbpaddr); 2701 (void) alpha_pal_swpctx((u_long)l->l_md.md_pcbpaddr);
2705 TLB_COUNT(activate_swpctx); 2702 TLB_COUNT(activate_swpctx);
2706 } else { 2703 } else {
2707 TLB_COUNT(activate_skip_swpctx); 2704 TLB_COUNT(activate_skip_swpctx);
2708 } 2705 }
2709 2706
2710 pmap_reference(pmap); 2707 pmap_reference(pmap);
2711 ci->ci_pmap = pmap; 2708 ci->ci_pmap = pmap;
2712 2709
2713 if (pmap != pmap_kernel()) { 2710 if (pmap != pmap_kernel()) {
2714 PMAP_ACT_UNLOCK(pmap); 2711 PMAP_ACT_UNLOCK(pmap);
2715 } 2712 }
2716} 2713}
2717 2714
2718/* 2715/*
2719 * pmap_deactivate: [ INTERFACE ] 2716 * pmap_deactivate: [ INTERFACE ]
2720 * 2717 *
2721 * Mark that the pmap used by the specified process is no longer 2718 * Mark that the pmap used by the specified process is no longer
2722 * in use by the processor. 2719 * in use by the processor.
2723 */ 2720 */
2724void 2721void
2725pmap_deactivate(struct lwp *l) 2722pmap_deactivate(struct lwp *l)
2726{ 2723{
2727 struct pmap * const pmap = l->l_proc->p_vmspace->vm_map.pmap; 2724 struct pmap * const pmap = l->l_proc->p_vmspace->vm_map.pmap;
2728 2725
2729#ifdef DEBUG 2726#ifdef DEBUG
2730 if (pmapdebug & PDB_FOLLOW) 2727 if (pmapdebug & PDB_FOLLOW)
2731 printf("pmap_deactivate(%p)\n", l); 2728 printf("pmap_deactivate(%p)\n", l);
2732#endif 2729#endif
2733 2730
2734 KASSERT(kpreempt_disabled()); 2731 KASSERT(kpreempt_disabled());
2735 2732
2736 struct cpu_info * const ci = curcpu(); 2733 struct cpu_info * const ci = curcpu();
2737 2734
2738 KASSERT(l == ci->ci_curlwp); 2735 KASSERT(l == ci->ci_curlwp);
2739 KASSERT(pmap == ci->ci_pmap); 2736 KASSERT(pmap == ci->ci_pmap);
2740 2737
2741 /* 2738 /*
2742 * There is no need to switch to a different PTBR here, 2739 * There is no need to switch to a different PTBR here,
2743 * because a pmap_activate() or SWPCTX is guaranteed 2740 * because a pmap_activate() or SWPCTX is guaranteed
2744 * before whatever lev1map we're on now is invalidated 2741 * before whatever lev1map we're on now is invalidated
2745 * or before user space is accessed again. 2742 * or before user space is accessed again.
2746 * 2743 *
2747 * Because only kernel mappings will be accessed before the 2744 * Because only kernel mappings will be accessed before the
2748 * next pmap_activate() call, we consider our CPU to be on 2745 * next pmap_activate() call, we consider our CPU to be on
2749 * the kernel pmap. 2746 * the kernel pmap.
2750 */ 2747 */
2751 ci->ci_pmap = pmap_kernel(); 2748 ci->ci_pmap = pmap_kernel();
2752 KASSERT(atomic_load_relaxed(&pmap->pm_count) > 1); 2749 KASSERT(atomic_load_relaxed(&pmap->pm_count) > 1);
2753 pmap_destroy(pmap); 2750 pmap_destroy(pmap);
2754} 2751}
2755 2752
2756/* 2753/*
2757 * pmap_zero_page: [ INTERFACE ] 2754 * pmap_zero_page: [ INTERFACE ]
2758 * 2755 *
2759 * Zero the specified (machine independent) page by mapping the page 2756 * Zero the specified (machine independent) page by mapping the page
2760 * into virtual memory and clear its contents, one machine dependent 2757 * into virtual memory and clear its contents, one machine dependent
2761 * page at a time. 2758 * page at a time.
2762 * 2759 *
2763 * Note: no locking is necessary in this function. 2760 * Note: no locking is necessary in this function.
2764 */ 2761 */
2765void 2762void
2766pmap_zero_page(paddr_t phys) 2763pmap_zero_page(paddr_t phys)
2767{ 2764{
2768 u_long *p0, *p1, *pend; 2765 u_long *p0, *p1, *pend;
2769 2766
2770#ifdef DEBUG 2767#ifdef DEBUG
2771 if (pmapdebug & PDB_FOLLOW) 2768 if (pmapdebug & PDB_FOLLOW)
2772 printf("pmap_zero_page(%lx)\n", phys); 2769 printf("pmap_zero_page(%lx)\n", phys);
2773#endif 2770#endif
2774 2771
2775 p0 = (u_long *)ALPHA_PHYS_TO_K0SEG(phys); 2772 p0 = (u_long *)ALPHA_PHYS_TO_K0SEG(phys);
2776 p1 = NULL; 2773 p1 = NULL;
2777 pend = (u_long *)((u_long)p0 + PAGE_SIZE); 2774 pend = (u_long *)((u_long)p0 + PAGE_SIZE);
2778 2775
2779 /* 2776 /*
2780 * Unroll the loop a bit, doing 16 quadwords per iteration. 2777 * Unroll the loop a bit, doing 16 quadwords per iteration.
2781 * Do only 8 back-to-back stores, and alternate registers. 2778 * Do only 8 back-to-back stores, and alternate registers.
2782 */ 2779 */
2783 do { 2780 do {
2784 __asm volatile( 2781 __asm volatile(
2785 "# BEGIN loop body\n" 2782 "# BEGIN loop body\n"
2786 " addq %2, (8 * 8), %1 \n" 2783 " addq %2, (8 * 8), %1 \n"
2787 " stq $31, (0 * 8)(%0) \n" 2784 " stq $31, (0 * 8)(%0) \n"
2788 " stq $31, (1 * 8)(%0) \n" 2785 " stq $31, (1 * 8)(%0) \n"
2789 " stq $31, (2 * 8)(%0) \n" 2786 " stq $31, (2 * 8)(%0) \n"
2790 " stq $31, (3 * 8)(%0) \n" 2787 " stq $31, (3 * 8)(%0) \n"
2791 " stq $31, (4 * 8)(%0) \n" 2788 " stq $31, (4 * 8)(%0) \n"
2792 " stq $31, (5 * 8)(%0) \n" 2789 " stq $31, (5 * 8)(%0) \n"
2793 " stq $31, (6 * 8)(%0) \n" 2790 " stq $31, (6 * 8)(%0) \n"
2794 " stq $31, (7 * 8)(%0) \n" 2791 " stq $31, (7 * 8)(%0) \n"
2795 " \n" 2792 " \n"
2796 " addq %3, (8 * 8), %0 \n" 2793 " addq %3, (8 * 8), %0 \n"
2797 " stq $31, (0 * 8)(%1) \n" 2794 " stq $31, (0 * 8)(%1) \n"
2798 " stq $31, (1 * 8)(%1) \n" 2795 " stq $31, (1 * 8)(%1) \n"
2799 " stq $31, (2 * 8)(%1) \n" 2796 " stq $31, (2 * 8)(%1) \n"
2800 " stq $31, (3 * 8)(%1) \n" 2797 " stq $31, (3 * 8)(%1) \n"
2801 " stq $31, (4 * 8)(%1) \n" 2798 " stq $31, (4 * 8)(%1) \n"
2802 " stq $31, (5 * 8)(%1) \n" 2799 " stq $31, (5 * 8)(%1) \n"
2803 " stq $31, (6 * 8)(%1) \n" 2800 " stq $31, (6 * 8)(%1) \n"
2804 " stq $31, (7 * 8)(%1) \n" 2801 " stq $31, (7 * 8)(%1) \n"
2805 " # END loop body" 2802 " # END loop body"
2806 : "=r" (p0), "=r" (p1) 2803 : "=r" (p0), "=r" (p1)
2807 : "0" (p0), "1" (p1) 2804 : "0" (p0), "1" (p1)
2808 : "memory"); 2805 : "memory");
2809 } while (p0 < pend); 2806 } while (p0 < pend);
2810} 2807}
2811 2808
2812/* 2809/*
2813 * pmap_copy_page: [ INTERFACE ] 2810 * pmap_copy_page: [ INTERFACE ]
2814 * 2811 *
2815 * Copy the specified (machine independent) page by mapping the page 2812 * Copy the specified (machine independent) page by mapping the page
2816 * into virtual memory and using memcpy to copy the page, one machine 2813 * into virtual memory and using memcpy to copy the page, one machine
2817 * dependent page at a time. 2814 * dependent page at a time.
2818 * 2815 *
2819 * Note: no locking is necessary in this function. 2816 * Note: no locking is necessary in this function.
2820 */ 2817 */
2821void 2818void
2822pmap_copy_page(paddr_t src, paddr_t dst) 2819pmap_copy_page(paddr_t src, paddr_t dst)
2823{ 2820{
2824 const void *s; 2821 const void *s;
2825 void *d; 2822 void *d;
2826 2823
2827#ifdef DEBUG 2824#ifdef DEBUG
2828 if (pmapdebug & PDB_FOLLOW) 2825 if (pmapdebug & PDB_FOLLOW)
2829 printf("pmap_copy_page(%lx, %lx)\n", src, dst); 2826 printf("pmap_copy_page(%lx, %lx)\n", src, dst);
2830#endif 2827#endif
2831 s = (const void *)ALPHA_PHYS_TO_K0SEG(src); 2828 s = (const void *)ALPHA_PHYS_TO_K0SEG(src);
2832 d = (void *)ALPHA_PHYS_TO_K0SEG(dst); 2829 d = (void *)ALPHA_PHYS_TO_K0SEG(dst);
2833 memcpy(d, s, PAGE_SIZE); 2830 memcpy(d, s, PAGE_SIZE);
2834} 2831}
2835 2832
2836/* 2833/*
2837 * pmap_pageidlezero: [ INTERFACE ] 2834 * pmap_pageidlezero: [ INTERFACE ]
2838 * 2835 *
2839 * Page zero'er for the idle loop. Returns true if the 2836 * Page zero'er for the idle loop. Returns true if the
2840 * page was zero'd, FALSE if we aborted for some reason. 2837 * page was zero'd, FALSE if we aborted for some reason.
2841 */ 2838 */
2842bool 2839bool
2843pmap_pageidlezero(paddr_t pa) 2840pmap_pageidlezero(paddr_t pa)
2844{ 2841{
2845 u_long *ptr; 2842 u_long *ptr;
2846 int i, cnt = PAGE_SIZE / sizeof(u_long); 2843 int i, cnt = PAGE_SIZE / sizeof(u_long);
2847 2844
2848 for (i = 0, ptr = (u_long *) ALPHA_PHYS_TO_K0SEG(pa); i < cnt; i++) { 2845 for (i = 0, ptr = (u_long *) ALPHA_PHYS_TO_K0SEG(pa); i < cnt; i++) {
2849 if (sched_curcpu_runnable_p()) { 2846 if (sched_curcpu_runnable_p()) {
2850 /* 2847 /*
2851 * An LWP has become ready. Abort now, 2848 * An LWP has become ready. Abort now,
2852 * so we don't keep it waiting while we 2849 * so we don't keep it waiting while we
2853 * finish zeroing the page. 2850 * finish zeroing the page.
2854 */ 2851 */
2855 return (false); 2852 return (false);
2856 } 2853 }
2857 *ptr++ = 0; 2854 *ptr++ = 0;
2858 } 2855 }
2859 2856
2860 return (true); 2857 return (true);
2861} 2858}
2862 2859
2863/* 2860/*
2864 * pmap_clear_modify: [ INTERFACE ] 2861 * pmap_clear_modify: [ INTERFACE ]
2865 * 2862 *
2866 * Clear the modify bits on the specified physical page. 2863 * Clear the modify bits on the specified physical page.
2867 */ 2864 */
2868bool 2865bool
2869pmap_clear_modify(struct vm_page *pg) 2866pmap_clear_modify(struct vm_page *pg)
2870{ 2867{
2871 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 2868 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
2872 bool rv = false; 2869 bool rv = false;
2873 kmutex_t *lock; 2870 kmutex_t *lock;
2874 struct pmap_tlb_context tlbctx; 2871 struct pmap_tlb_context tlbctx;
2875 2872
2876#ifdef DEBUG 2873#ifdef DEBUG
2877 if (pmapdebug & PDB_FOLLOW) 2874 if (pmapdebug & PDB_FOLLOW)
2878 printf("pmap_clear_modify(%p)\n", pg); 2875 printf("pmap_clear_modify(%p)\n", pg);
2879#endif 2876#endif
2880 2877
2881 pmap_tlb_context_init(&tlbctx, TLB_CTX_F_PV); 2878 pmap_tlb_context_init(&tlbctx, TLB_CTX_F_PV);
2882 2879
2883 PMAP_HEAD_TO_MAP_LOCK(); 2880 PMAP_HEAD_TO_MAP_LOCK();
2884 lock = pmap_pvh_lock(pg); 2881 lock = pmap_pvh_lock(pg);
2885 mutex_enter(lock); 2882 mutex_enter(lock);
2886 2883
2887 if (md->pvh_listx & PGA_MODIFIED) { 2884 if (md->pvh_listx & PGA_MODIFIED) {
2888 rv = true; 2885 rv = true;
2889 pmap_changebit(pg, PG_FOW, ~0UL, &tlbctx); 2886 pmap_changebit(pg, PG_FOW, ~0UL, &tlbctx);
2890 md->pvh_listx &= ~PGA_MODIFIED; 2887 md->pvh_listx &= ~PGA_MODIFIED;
2891 } 2888 }
2892 2889
2893 mutex_exit(lock); 2890 mutex_exit(lock);
2894 PMAP_HEAD_TO_MAP_UNLOCK(); 2891 PMAP_HEAD_TO_MAP_UNLOCK();
2895 2892
2896 pmap_tlb_shootnow(&tlbctx); 2893 pmap_tlb_shootnow(&tlbctx);
2897 TLB_COUNT(reason_clear_modify); 2894 TLB_COUNT(reason_clear_modify);
2898 2895
2899 return (rv); 2896 return (rv);
2900} 2897}
2901 2898
2902/* 2899/*
2903 * pmap_clear_reference: [ INTERFACE ] 2900 * pmap_clear_reference: [ INTERFACE ]
2904 * 2901 *
2905 * Clear the reference bit on the specified physical page. 2902 * Clear the reference bit on the specified physical page.
2906 */ 2903 */
2907bool 2904bool
2908pmap_clear_reference(struct vm_page *pg) 2905pmap_clear_reference(struct vm_page *pg)
2909{ 2906{
2910 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 2907 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
2911 bool rv = false; 2908 bool rv = false;
2912 kmutex_t *lock; 2909 kmutex_t *lock;
2913 struct pmap_tlb_context tlbctx; 2910 struct pmap_tlb_context tlbctx;
2914 2911
2915#ifdef DEBUG 2912#ifdef DEBUG
2916 if (pmapdebug & PDB_FOLLOW) 2913 if (pmapdebug & PDB_FOLLOW)
2917 printf("pmap_clear_reference(%p)\n", pg); 2914 printf("pmap_clear_reference(%p)\n", pg);
2918#endif 2915#endif
2919 2916
2920 pmap_tlb_context_init(&tlbctx, TLB_CTX_F_PV); 2917 pmap_tlb_context_init(&tlbctx, TLB_CTX_F_PV);
2921 2918
2922 PMAP_HEAD_TO_MAP_LOCK(); 2919 PMAP_HEAD_TO_MAP_LOCK();
2923 lock = pmap_pvh_lock(pg); 2920 lock = pmap_pvh_lock(pg);
2924 mutex_enter(lock); 2921 mutex_enter(lock);
2925 2922
2926 if (md->pvh_listx & PGA_REFERENCED) { 2923 if (md->pvh_listx & PGA_REFERENCED) {
2927 rv = true; 2924 rv = true;
2928 pmap_changebit(pg, PG_FOR | PG_FOW | PG_FOE, ~0UL, &tlbctx); 2925 pmap_changebit(pg, PG_FOR | PG_FOW | PG_FOE, ~0UL, &tlbctx);
2929 md->pvh_listx &= ~PGA_REFERENCED; 2926 md->pvh_listx &= ~PGA_REFERENCED;
2930 } 2927 }
2931 2928
2932 mutex_exit(lock); 2929 mutex_exit(lock);
2933 PMAP_HEAD_TO_MAP_UNLOCK(); 2930 PMAP_HEAD_TO_MAP_UNLOCK();
2934 2931
2935 pmap_tlb_shootnow(&tlbctx); 2932 pmap_tlb_shootnow(&tlbctx);
2936 TLB_COUNT(reason_clear_reference); 2933 TLB_COUNT(reason_clear_reference);
2937 2934
2938 return (rv); 2935 return (rv);
2939} 2936}
2940 2937
2941/* 2938/*
2942 * pmap_is_referenced: [ INTERFACE ] 2939 * pmap_is_referenced: [ INTERFACE ]
2943 * 2940 *
2944 * Return whether or not the specified physical page is referenced 2941 * Return whether or not the specified physical page is referenced
2945 * by any physical maps. 2942 * by any physical maps.
2946 */ 2943 */
2947/* See <machine/pmap.h> */ 2944/* See <machine/pmap.h> */
2948 2945
2949/* 2946/*
2950 * pmap_is_modified: [ INTERFACE ] 2947 * pmap_is_modified: [ INTERFACE ]
2951 * 2948 *
2952 * Return whether or not the specified physical page is modified 2949 * Return whether or not the specified physical page is modified
2953 * by any physical maps. 2950 * by any physical maps.
2954 */ 2951 */
2955/* See <machine/pmap.h> */ 2952/* See <machine/pmap.h> */
2956 2953
2957/* 2954/*
2958 * pmap_phys_address: [ INTERFACE ] 2955 * pmap_phys_address: [ INTERFACE ]
2959 * 2956 *
2960 * Return the physical address corresponding to the specified 2957 * Return the physical address corresponding to the specified
2961 * cookie. Used by the device pager to decode a device driver's 2958 * cookie. Used by the device pager to decode a device driver's
2962 * mmap entry point return value. 2959 * mmap entry point return value.
2963 * 2960 *
2964 * Note: no locking is necessary in this function. 2961 * Note: no locking is necessary in this function.
2965 */ 2962 */
2966paddr_t 2963paddr_t
2967pmap_phys_address(paddr_t ppn) 2964pmap_phys_address(paddr_t ppn)
2968{ 2965{
2969 2966
2970 return (alpha_ptob(ppn)); 2967 return (alpha_ptob(ppn));
2971} 2968}
2972 2969
2973/* 2970/*
2974 * Miscellaneous support routines follow 2971 * Miscellaneous support routines follow
2975 */ 2972 */
2976 2973
2977/* 2974/*
2978 * alpha_protection_init: 2975 * alpha_protection_init:
2979 * 2976 *
2980 * Initialize Alpha protection code array. 2977 * Initialize Alpha protection code array.
2981 * 2978 *
2982 * Note: no locking is necessary in this function. 2979 * Note: no locking is necessary in this function.
2983 */ 2980 */
2984static void 2981static void
2985alpha_protection_init(void) 2982alpha_protection_init(void)
2986{ 2983{
2987 int prot, *kp, *up; 2984 int prot, *kp, *up;
2988 2985
2989 kp = protection_codes[0]; 2986 kp = protection_codes[0];
2990 up = protection_codes[1]; 2987 up = protection_codes[1];
2991 2988
2992 for (prot = 0; prot < 8; prot++) { 2989 for (prot = 0; prot < 8; prot++) {
2993 kp[prot] = PG_ASM; 2990 kp[prot] = PG_ASM;
2994 up[prot] = 0; 2991 up[prot] = 0;
2995 2992
2996 if (prot & VM_PROT_READ) { 2993 if (prot & VM_PROT_READ) {
2997 kp[prot] |= PG_KRE; 2994 kp[prot] |= PG_KRE;
2998 up[prot] |= PG_KRE | PG_URE; 2995 up[prot] |= PG_KRE | PG_URE;
2999 } 2996 }
3000 if (prot & VM_PROT_WRITE) { 2997 if (prot & VM_PROT_WRITE) {
3001 kp[prot] |= PG_KWE; 2998 kp[prot] |= PG_KWE;
3002 up[prot] |= PG_KWE | PG_UWE; 2999 up[prot] |= PG_KWE | PG_UWE;
3003 } 3000 }
3004 if (prot & VM_PROT_EXECUTE) { 3001 if (prot & VM_PROT_EXECUTE) {
3005 kp[prot] |= PG_EXEC | PG_KRE; 3002 kp[prot] |= PG_EXEC | PG_KRE;
3006 up[prot] |= PG_EXEC | PG_KRE | PG_URE; 3003 up[prot] |= PG_EXEC | PG_KRE | PG_URE;
3007 } else { 3004 } else {
3008 kp[prot] |= PG_FOE; 3005 kp[prot] |= PG_FOE;
3009 up[prot] |= PG_FOE; 3006 up[prot] |= PG_FOE;
3010 } 3007 }
3011 } 3008 }
3012} 3009}
3013 3010
3014/* 3011/*
3015 * pmap_remove_mapping: 3012 * pmap_remove_mapping:
3016 * 3013 *
3017 * Invalidate a single page denoted by pmap/va. 3014 * Invalidate a single page denoted by pmap/va.
3018 * 3015 *
3019 * If (pte != NULL), it is the already computed PTE for the page. 3016 * If (pte != NULL), it is the already computed PTE for the page.
3020 * 3017 *
3021 * Note: locking in this function is complicated by the fact 3018 * Note: locking in this function is complicated by the fact
3022 * that we can be called when the PV list is already locked. 3019 * that we can be called when the PV list is already locked.
3023 * (pmap_page_protect()). In this case, the caller must be 3020 * (pmap_page_protect()). In this case, the caller must be
3024 * careful to get the next PV entry while we remove this entry 3021 * careful to get the next PV entry while we remove this entry
3025 * from beneath it. We assume that the pmap itself is already 3022 * from beneath it. We assume that the pmap itself is already
3026 * locked; dolock applies only to the PV list. 3023 * locked; dolock applies only to the PV list.
3027 * 3024 *
3028 * Returns important PTE bits that the caller needs to check for 3025 * Returns important PTE bits that the caller needs to check for
3029 * TLB / I-stream invalidation purposes. 3026 * TLB / I-stream invalidation purposes.
3030 */ 3027 */
3031static pt_entry_t 3028static pt_entry_t
3032pmap_remove_mapping(pmap_t pmap, vaddr_t va, pt_entry_t *pte, 3029pmap_remove_mapping(pmap_t pmap, vaddr_t va, pt_entry_t *pte,
3033 bool dolock, pv_entry_t *opvp, struct pmap_tlb_context * const tlbctx) 3030 bool dolock, pv_entry_t *opvp, struct pmap_tlb_context * const tlbctx)
3034{ 3031{
3035 pt_entry_t opte; 3032 pt_entry_t opte;
3036 paddr_t pa; 3033 paddr_t pa;
3037 struct vm_page *pg; /* if != NULL, page is managed */ 3034 struct vm_page *pg; /* if != NULL, page is managed */
3038 3035
3039#ifdef DEBUG 3036#ifdef DEBUG
3040 if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT)) 3037 if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT))
3041 printf("pmap_remove_mapping(%p, %lx, %p, %d, %p, %p)\n", 3038 printf("pmap_remove_mapping(%p, %lx, %p, %d, %p, %p)\n",
3042 pmap, va, pte, dolock, opvp, tlbctx); 3039 pmap, va, pte, dolock, opvp, tlbctx);
3043#endif 3040#endif
3044 3041
3045 /* 3042 /*
3046 * PTE not provided, compute it from pmap and va. 3043 * PTE not provided, compute it from pmap and va.
3047 */ 3044 */
3048 if (pte == NULL) { 3045 if (pte == NULL) {
3049 pte = pmap_l3pte(pmap_lev1map(pmap), va, NULL); 3046 pte = pmap_l3pte(pmap_lev1map(pmap), va, NULL);
3050 if (pmap_pte_v(pte) == 0) 3047 if (pmap_pte_v(pte) == 0)
3051 return 0; 3048 return 0;
3052 } 3049 }
3053 3050
3054 opte = *pte; 3051 opte = *pte;
3055 3052
3056 pa = PG_PFNUM(opte) << PGSHIFT; 3053 pa = PG_PFNUM(opte) << PGSHIFT;
3057 3054
3058 /* 3055 /*
3059 * Update statistics 3056 * Update statistics
3060 */ 3057 */
3061 if (pmap_pte_w(pte)) 3058 if (pmap_pte_w(pte))
3062 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1); 3059 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1);
3063 PMAP_STAT_DECR(pmap->pm_stats.resident_count, 1); 3060 PMAP_STAT_DECR(pmap->pm_stats.resident_count, 1);
3064 3061
3065 /* 3062 /*
3066 * Invalidate the PTE after saving the reference modify info. 3063 * Invalidate the PTE after saving the reference modify info.
3067 */ 3064 */
3068#ifdef DEBUG 3065#ifdef DEBUG
3069 if (pmapdebug & PDB_REMOVE) 3066 if (pmapdebug & PDB_REMOVE)
3070 printf("remove: invalidating pte at %p\n", pte); 3067 printf("remove: invalidating pte at %p\n", pte);
3071#endif 3068#endif
3072 atomic_store_relaxed(pte, PG_NV); 3069 atomic_store_relaxed(pte, PG_NV);
3073 3070
3074 /* 3071 /*
3075 * If we're removing a user mapping, check to see if we 3072 * If we're removing a user mapping, check to see if we
3076 * can free page table pages. 3073 * can free page table pages.
3077 */ 3074 */
3078 if (pmap != pmap_kernel()) { 3075 if (pmap != pmap_kernel()) {
3079 /* 3076 /*
3080 * Delete the reference on the level 3 table. It will 3077 * Delete the reference on the level 3 table. It will
3081 * delete references on the level 2 and 1 tables as 3078 * delete references on the level 2 and 1 tables as
3082 * appropriate. 3079 * appropriate.
3083 */ 3080 */
3084 pmap_l3pt_delref(pmap, va, pte, tlbctx); 3081 pmap_l3pt_delref(pmap, va, pte, tlbctx);
3085 } 3082 }
3086 3083
3087 if (opte & PG_PVLIST) { 3084 if (opte & PG_PVLIST) {
3088 /* 3085 /*
3089 * Remove it from the PV table. 3086 * Remove it from the PV table.
3090 */ 3087 */
3091 pg = PHYS_TO_VM_PAGE(pa); 3088 pg = PHYS_TO_VM_PAGE(pa);
3092 KASSERT(pg != NULL); 3089 KASSERT(pg != NULL);
3093 pmap_pv_remove(pmap, pg, va, dolock, opvp, tlbctx); 3090 pmap_pv_remove(pmap, pg, va, dolock, opvp, tlbctx);
3094 KASSERT(opvp == NULL || *opvp != NULL); 3091 KASSERT(opvp == NULL || *opvp != NULL);
3095 } 3092 }
3096 3093
3097 return opte & (PG_V | PG_ASM | PG_EXEC); 3094 return opte & (PG_V | PG_ASM | PG_EXEC);
3098} 3095}
3099 3096
3100/* 3097/*
3101 * pmap_changebit: 3098 * pmap_changebit:
3102 * 3099 *
3103 * Set or clear the specified PTE bits for all mappings on the 3100 * Set or clear the specified PTE bits for all mappings on the
3104 * specified page. 3101 * specified page.
3105 * 3102 *
3106 * Note: we assume that the pv_head is already locked, and that 3103 * Note: we assume that the pv_head is already locked, and that
3107 * the caller has acquired a PV->pmap mutex so that we can lock 3104 * the caller has acquired a PV->pmap mutex so that we can lock
3108 * the pmaps as we encounter them. 3105 * the pmaps as we encounter them.
3109 */ 3106 */
3110static void 3107static void
3111pmap_changebit(struct vm_page *pg, pt_entry_t set, pt_entry_t mask, 3108pmap_changebit(struct vm_page *pg, pt_entry_t set, pt_entry_t mask,
3112 struct pmap_tlb_context * const tlbctx) 3109 struct pmap_tlb_context * const tlbctx)
3113{ 3110{
3114 pv_entry_t pv; 3111 pv_entry_t pv;
3115 pt_entry_t *pte, npte, opte; 3112 pt_entry_t *pte, npte, opte;
3116 3113
3117#ifdef DEBUG 3114#ifdef DEBUG
3118 if (pmapdebug & PDB_BITS) 3115 if (pmapdebug & PDB_BITS)
3119 printf("pmap_changebit(%p, 0x%lx, 0x%lx)\n", 3116 printf("pmap_changebit(%p, 0x%lx, 0x%lx)\n",
3120 pg, set, mask); 3117 pg, set, mask);
3121#endif 3118#endif
3122 3119
3123 /* 3120 /*
3124 * Loop over all current mappings setting/clearing as apropos. 3121 * Loop over all current mappings setting/clearing as apropos.
3125 */ 3122 */
3126 for (pv = VM_MDPAGE_PVS(pg); pv != NULL; pv = pv->pv_next) { 3123 for (pv = VM_MDPAGE_PVS(pg); pv != NULL; pv = pv->pv_next) {
3127 PMAP_LOCK(pv->pv_pmap); 3124 PMAP_LOCK(pv->pv_pmap);
3128 3125
3129 pte = pv->pv_pte; 3126 pte = pv->pv_pte;
3130 3127
3131 opte = atomic_load_relaxed(pte); 3128 opte = atomic_load_relaxed(pte);
3132 npte = (opte | set) & mask; 3129 npte = (opte | set) & mask;
3133 if (npte != opte) { 3130 if (npte != opte) {
3134 atomic_store_relaxed(pte, npte); 3131 atomic_store_relaxed(pte, npte);
3135 pmap_tlb_shootdown_pv(pv->pv_pmap, pv->pv_va, 3132 pmap_tlb_shootdown_pv(pv->pv_pmap, pv->pv_va,
3136 opte, tlbctx); 3133 opte, tlbctx);
3137 } 3134 }
3138 PMAP_UNLOCK(pv->pv_pmap); 3135 PMAP_UNLOCK(pv->pv_pmap);
3139 } 3136 }
3140} 3137}
3141 3138
3142/* 3139/*
3143 * pmap_emulate_reference: 3140 * pmap_emulate_reference:
3144 * 3141 *
3145 * Emulate reference and/or modified bit hits. 3142 * Emulate reference and/or modified bit hits.
3146 * Return 1 if this was an execute fault on a non-exec mapping, 3143 * Return 1 if this was an execute fault on a non-exec mapping,
3147 * otherwise return 0. 3144 * otherwise return 0.
3148 */ 3145 */
3149int 3146int
3150pmap_emulate_reference(struct lwp *l, vaddr_t v, int user, int type) 3147pmap_emulate_reference(struct lwp *l, vaddr_t v, int user, int type)
3151{ 3148{
3152 struct pmap *pmap = l->l_proc->p_vmspace->vm_map.pmap; 3149 struct pmap *pmap = l->l_proc->p_vmspace->vm_map.pmap;
3153 pt_entry_t faultoff, *pte; 3150 pt_entry_t faultoff, *pte;
3154 struct vm_page *pg; 3151 struct vm_page *pg;
3155 paddr_t pa; 3152 paddr_t pa;
3156 bool didlock = false; 3153 bool didlock = false;
3157 bool exec = false; 3154 bool exec = false;
3158 kmutex_t *lock; 3155 kmutex_t *lock;
3159 3156
3160#ifdef DEBUG 3157#ifdef DEBUG
3161 if (pmapdebug & PDB_FOLLOW) 3158 if (pmapdebug & PDB_FOLLOW)
3162 printf("pmap_emulate_reference: %p, 0x%lx, %d, %d\n", 3159 printf("pmap_emulate_reference: %p, 0x%lx, %d, %d\n",
3163 l, v, user, type); 3160 l, v, user, type);
3164#endif 3161#endif
3165 3162
3166 /* 3163 /*
3167 * Convert process and virtual address to physical address. 3164 * Convert process and virtual address to physical address.
3168 */ 3165 */
3169 if (v >= VM_MIN_KERNEL_ADDRESS) { 3166 if (v >= VM_MIN_KERNEL_ADDRESS) {
3170 if (user) 3167 if (user)
3171 panic("pmap_emulate_reference: user ref to kernel"); 3168 panic("pmap_emulate_reference: user ref to kernel");
3172 /* 3169 /*
3173 * No need to lock here; kernel PT pages never go away. 3170 * No need to lock here; kernel PT pages never go away.
3174 */ 3171 */
3175 pte = PMAP_KERNEL_PTE(v); 3172 pte = PMAP_KERNEL_PTE(v);
3176 } else { 3173 } else {
3177#ifdef DIAGNOSTIC 3174#ifdef DIAGNOSTIC
3178 if (l == NULL) 3175 if (l == NULL)
3179 panic("pmap_emulate_reference: bad proc"); 3176 panic("pmap_emulate_reference: bad proc");
3180 if (l->l_proc->p_vmspace == NULL) 3177 if (l->l_proc->p_vmspace == NULL)
3181 panic("pmap_emulate_reference: bad p_vmspace"); 3178 panic("pmap_emulate_reference: bad p_vmspace");
3182#endif 3179#endif
3183 PMAP_LOCK(pmap); 3180 PMAP_LOCK(pmap);
3184 didlock = true; 3181 didlock = true;
3185 pte = pmap_l3pte(pmap_lev1map(pmap), v, NULL); 3182 pte = pmap_l3pte(pmap_lev1map(pmap), v, NULL);
3186 /* 3183 /*
3187 * We'll unlock below where we're done with the PTE. 3184 * We'll unlock below where we're done with the PTE.
3188 */ 3185 */
3189 } 3186 }
3190 exec = pmap_pte_exec(pte); 3187 exec = pmap_pte_exec(pte);
3191 if (!exec && type == ALPHA_MMCSR_FOE) { 3188 if (!exec && type == ALPHA_MMCSR_FOE) {
3192 if (didlock) 3189 if (didlock)
3193 PMAP_UNLOCK(pmap); 3190 PMAP_UNLOCK(pmap);
3194 return (1); 3191 return (1);
3195 } 3192 }
3196#ifdef DEBUG 3193#ifdef DEBUG
3197 if (pmapdebug & PDB_FOLLOW) { 3194 if (pmapdebug & PDB_FOLLOW) {
3198 printf("\tpte = %p, ", pte); 3195 printf("\tpte = %p, ", pte);
3199 printf("*pte = 0x%lx\n", *pte); 3196 printf("*pte = 0x%lx\n", *pte);
3200 } 3197 }
3201#endif 3198#endif
3202 3199
3203 pa = pmap_pte_pa(pte); 3200 pa = pmap_pte_pa(pte);
3204 3201
3205 /* 3202 /*
3206 * We're now done with the PTE. If it was a user pmap, unlock 3203 * We're now done with the PTE. If it was a user pmap, unlock
3207 * it now. 3204 * it now.
3208 */ 3205 */
3209 if (didlock) 3206 if (didlock)
3210 PMAP_UNLOCK(pmap); 3207 PMAP_UNLOCK(pmap);
3211 3208
3212#ifdef DEBUG 3209#ifdef DEBUG
3213 if (pmapdebug & PDB_FOLLOW) 3210 if (pmapdebug & PDB_FOLLOW)
3214 printf("\tpa = 0x%lx\n", pa); 3211 printf("\tpa = 0x%lx\n", pa);
3215#endif 3212#endif
3216#ifdef DIAGNOSTIC 3213#ifdef DIAGNOSTIC
3217 if (!uvm_pageismanaged(pa)) 3214 if (!uvm_pageismanaged(pa))
3218 panic("pmap_emulate_reference(%p, 0x%lx, %d, %d): " 3215 panic("pmap_emulate_reference(%p, 0x%lx, %d, %d): "
3219 "pa 0x%lx not managed", l, v, user, type, pa); 3216 "pa 0x%lx not managed", l, v, user, type, pa);
3220#endif 3217#endif
3221 3218
3222 /* 3219 /*
3223 * Twiddle the appropriate bits to reflect the reference 3220 * Twiddle the appropriate bits to reflect the reference
3224 * and/or modification.. 3221 * and/or modification..
3225 * 3222 *
3226 * The rules: 3223 * The rules:
3227 * (1) always mark page as used, and 3224 * (1) always mark page as used, and
3228 * (2) if it was a write fault, mark page as modified. 3225 * (2) if it was a write fault, mark page as modified.
3229 */ 3226 */
3230 pg = PHYS_TO_VM_PAGE(pa); 3227 pg = PHYS_TO_VM_PAGE(pa);
3231 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 3228 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
3232 struct pmap_tlb_context tlbctx; 3229 struct pmap_tlb_context tlbctx;
3233 3230
3234 pmap_tlb_context_init(&tlbctx, TLB_CTX_F_PV); 3231 pmap_tlb_context_init(&tlbctx, TLB_CTX_F_PV);
3235 3232
3236 PMAP_HEAD_TO_MAP_LOCK(); 3233 PMAP_HEAD_TO_MAP_LOCK();
3237 lock = pmap_pvh_lock(pg); 3234 lock = pmap_pvh_lock(pg);
3238 mutex_enter(lock); 3235 mutex_enter(lock);
3239 3236
3240 if (type == ALPHA_MMCSR_FOW) { 3237 if (type == ALPHA_MMCSR_FOW) {
3241 md->pvh_listx |= (PGA_REFERENCED|PGA_MODIFIED); 3238 md->pvh_listx |= (PGA_REFERENCED|PGA_MODIFIED);
3242 faultoff = PG_FOR | PG_FOW; 3239 faultoff = PG_FOR | PG_FOW;
3243 } else { 3240 } else {
3244 md->pvh_listx |= PGA_REFERENCED; 3241 md->pvh_listx |= PGA_REFERENCED;
3245 faultoff = PG_FOR; 3242 faultoff = PG_FOR;
3246 if (exec) { 3243 if (exec) {
3247 faultoff |= PG_FOE; 3244 faultoff |= PG_FOE;
3248 } 3245 }
3249 } 3246 }
3250 pmap_changebit(pg, 0, ~faultoff, &tlbctx); 3247 pmap_changebit(pg, 0, ~faultoff, &tlbctx);
3251 3248
3252 mutex_exit(lock); 3249 mutex_exit(lock);
3253 PMAP_HEAD_TO_MAP_UNLOCK(); 3250 PMAP_HEAD_TO_MAP_UNLOCK();
3254 3251
3255 pmap_tlb_shootnow(&tlbctx); 3252 pmap_tlb_shootnow(&tlbctx);
3256 TLB_COUNT(reason_emulate_reference); 3253 TLB_COUNT(reason_emulate_reference);
3257 3254
3258 return (0); 3255 return (0);
3259} 3256}
3260 3257
3261#ifdef DEBUG 3258#ifdef DEBUG
3262/* 3259/*
3263 * pmap_pv_dump: 3260 * pmap_pv_dump:
3264 * 3261 *
3265 * Dump the physical->virtual data for the specified page. 3262 * Dump the physical->virtual data for the specified page.
3266 */ 3263 */
3267void 3264void
3268pmap_pv_dump(paddr_t pa) 3265pmap_pv_dump(paddr_t pa)
3269{ 3266{
3270 struct vm_page *pg; 3267 struct vm_page *pg;
3271 struct vm_page_md *md; 3268 struct vm_page_md *md;
3272 pv_entry_t pv; 3269 pv_entry_t pv;
3273 kmutex_t *lock; 3270 kmutex_t *lock;
3274 3271
3275 pg = PHYS_TO_VM_PAGE(pa); 3272 pg = PHYS_TO_VM_PAGE(pa);
3276 md = VM_PAGE_TO_MD(pg); 3273 md = VM_PAGE_TO_MD(pg);
3277 3274
3278 lock = pmap_pvh_lock(pg); 3275 lock = pmap_pvh_lock(pg);
3279 mutex_enter(lock); 3276 mutex_enter(lock);
3280 3277
3281 printf("pa 0x%lx (attrs = 0x%x):\n", pa, md->pvh_listx & PGA_ATTRS); 3278 printf("pa 0x%lx (attrs = 0x%lx):\n", pa, md->pvh_listx & PGA_ATTRS);
3282 for (pv = VM_MDPAGE_PVS(pg); pv != NULL; pv = pv->pv_next) 3279 for (pv = VM_MDPAGE_PVS(pg); pv != NULL; pv = pv->pv_next)
3283 printf(" pmap %p, va 0x%lx\n", 3280 printf(" pmap %p, va 0x%lx\n",
3284 pv->pv_pmap, pv->pv_va); 3281 pv->pv_pmap, pv->pv_va);
3285 printf("\n"); 3282 printf("\n");
3286 3283
3287 mutex_exit(lock); 3284 mutex_exit(lock);
3288} 3285}
3289#endif 3286#endif
3290 3287
3291/* 3288/*
3292 * vtophys: 3289 * vtophys:
3293 * 3290 *
3294 * Return the physical address corresponding to the K0SEG or 3291 * Return the physical address corresponding to the K0SEG or
3295 * K1SEG address provided. 3292 * K1SEG address provided.
3296 * 3293 *
3297 * Note: no locking is necessary in this function. 3294 * Note: no locking is necessary in this function.
3298 */ 3295 */
3299static bool 3296static bool
3300vtophys_internal(vaddr_t const vaddr, paddr_t * const pap) 3297vtophys_internal(vaddr_t const vaddr, paddr_t * const pap)
3301{ 3298{
3302 paddr_t pa; 3299 paddr_t pa;
3303 3300
3304 KASSERT(vaddr >= ALPHA_K0SEG_BASE); 3301 KASSERT(vaddr >= ALPHA_K0SEG_BASE);
3305 3302
3306 if (vaddr <= ALPHA_K0SEG_END) { 3303 if (vaddr <= ALPHA_K0SEG_END) {
3307 pa = ALPHA_K0SEG_TO_PHYS(vaddr); 3304 pa = ALPHA_K0SEG_TO_PHYS(vaddr);
3308 } else { 3305 } else {
3309 pt_entry_t * const pte = PMAP_KERNEL_PTE(vaddr); 3306 pt_entry_t * const pte = PMAP_KERNEL_PTE(vaddr);
3310 if (__predict_false(! pmap_pte_v(pte))) { 3307 if (__predict_false(! pmap_pte_v(pte))) {
3311 return false; 3308 return false;
3312 } 3309 }
3313 pa = pmap_pte_pa(pte) | (vaddr & PGOFSET); 3310 pa = pmap_pte_pa(pte) | (vaddr & PGOFSET);
3314 } 3311 }
3315 3312
3316 if (pap != NULL) { 3313 if (pap != NULL) {
3317 *pap = pa; 3314 *pap = pa;
3318 } 3315 }
3319 3316
3320 return true; 3317 return true;
3321} 3318}
3322 3319
3323paddr_t 3320paddr_t
3324vtophys(vaddr_t const vaddr) 3321vtophys(vaddr_t const vaddr)
3325{ 3322{
3326 paddr_t pa; 3323 paddr_t pa;
3327 3324
3328 if (__predict_false(! vtophys_internal(vaddr, &pa))) 3325 if (__predict_false(! vtophys_internal(vaddr, &pa)))
3329 pa = 0; 3326 pa = 0;
3330 return pa; 3327 return pa;
3331} 3328}
3332 3329
3333/******************** pv_entry management ********************/ 3330/******************** pv_entry management ********************/
3334 3331
3335/* 3332/*
3336 * pmap_pv_enter: 3333 * pmap_pv_enter:
3337 * 3334 *
3338 * Add a physical->virtual entry to the pv_table. 3335 * Add a physical->virtual entry to the pv_table.
3339 */ 3336 */
3340static int 3337static int
3341pmap_pv_enter(pmap_t pmap, struct vm_page *pg, vaddr_t va, pt_entry_t *pte, 3338pmap_pv_enter(pmap_t pmap, struct vm_page *pg, vaddr_t va, pt_entry_t *pte,
3342 bool dolock, pv_entry_t newpv) 3339 bool dolock, pv_entry_t newpv)
3343{ 3340{
3344 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 3341 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
3345 kmutex_t *lock; 3342 kmutex_t *lock;
3346 3343
3347 /* 3344 /*
3348 * Allocate and fill in the new pv_entry. 3345 * Allocate and fill in the new pv_entry.
3349 */ 3346 */
3350 if (newpv == NULL) { 3347 if (newpv == NULL) {
3351 newpv = pmap_pv_alloc(); 3348 newpv = pmap_pv_alloc();
3352 if (newpv == NULL) 3349 if (newpv == NULL)
3353 return ENOMEM; 3350 return ENOMEM;
3354 } 3351 }
3355 newpv->pv_va = va; 3352 newpv->pv_va = va;
3356 newpv->pv_pmap = pmap; 3353 newpv->pv_pmap = pmap;
3357 newpv->pv_pte = pte; 3354 newpv->pv_pte = pte;
3358 3355
3359 if (dolock) { 3356 if (dolock) {
3360 lock = pmap_pvh_lock(pg); 3357 lock = pmap_pvh_lock(pg);
3361 mutex_enter(lock); 3358 mutex_enter(lock);
3362 } 3359 }
3363 3360
3364#ifdef DEBUG 3361#ifdef DEBUG
3365 { 3362 {
3366 pv_entry_t pv; 3363 pv_entry_t pv;
3367 /* 3364 /*
3368 * Make sure the entry doesn't already exist. 3365 * Make sure the entry doesn't already exist.
3369 */ 3366 */
3370 for (pv = VM_MDPAGE_PVS(pg); pv != NULL; pv = pv->pv_next) { 3367 for (pv = VM_MDPAGE_PVS(pg); pv != NULL; pv = pv->pv_next) {
3371 if (pmap == pv->pv_pmap && va == pv->pv_va) { 3368 if (pmap == pv->pv_pmap && va == pv->pv_va) {
3372 printf("pmap = %p, va = 0x%lx\n", pmap, va); 3369 printf("pmap = %p, va = 0x%lx\n", pmap, va);
3373 panic("pmap_pv_enter: already in pv table"); 3370 panic("pmap_pv_enter: already in pv table");
3374 } 3371 }
3375 } 3372 }
3376 } 3373 }
3377#endif 3374#endif
3378 3375
3379 /* 3376 /*
3380 * ...and put it in the list. 3377 * ...and put it in the list.
3381 */ 3378 */
3382 uintptr_t const attrs = md->pvh_listx & PGA_ATTRS; 3379 uintptr_t const attrs = md->pvh_listx & PGA_ATTRS;
3383 newpv->pv_next = (struct pv_entry *)(md->pvh_listx & ~PGA_ATTRS); 3380 newpv->pv_next = (struct pv_entry *)(md->pvh_listx & ~PGA_ATTRS);
3384 md->pvh_listx = (uintptr_t)newpv | attrs; 3381 md->pvh_listx = (uintptr_t)newpv | attrs;
3385 LIST_INSERT_HEAD(&pmap->pm_pvents, newpv, pv_link); 3382 LIST_INSERT_HEAD(&pmap->pm_pvents, newpv, pv_link);
3386 3383
3387 if (dolock) { 3384 if (dolock) {
3388 mutex_exit(lock); 3385 mutex_exit(lock);
3389 } 3386 }
3390 3387
3391 return 0; 3388 return 0;
3392} 3389}
3393 3390
3394/* 3391/*
3395 * pmap_pv_remove: 3392 * pmap_pv_remove:
3396 * 3393 *
3397 * Remove a physical->virtual entry from the pv_table. 3394 * Remove a physical->virtual entry from the pv_table.
3398 */ 3395 */
3399static void 3396static void
3400pmap_pv_remove(pmap_t pmap, struct vm_page *pg, vaddr_t va, bool dolock, 3397pmap_pv_remove(pmap_t pmap, struct vm_page *pg, vaddr_t va, bool dolock,
3401 pv_entry_t *opvp, struct pmap_tlb_context * const tlbctx) 3398 pv_entry_t *opvp, struct pmap_tlb_context * const tlbctx)
3402{ 3399{
3403 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 3400 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
3404 pv_entry_t pv, *pvp; 3401 pv_entry_t pv, *pvp;
3405 kmutex_t *lock; 3402 kmutex_t *lock;
3406 3403
3407 if (dolock) { 3404 if (dolock) {
3408 lock = pmap_pvh_lock(pg); 3405 lock = pmap_pvh_lock(pg);
3409 mutex_enter(lock); 3406 mutex_enter(lock);
3410 } else { 3407 } else {
3411 lock = NULL; /* XXX stupid gcc */ 3408 lock = NULL; /* XXX stupid gcc */
3412 } 3409 }
3413 3410
3414 /* 3411 /*
3415 * Find the entry to remove. 3412 * Find the entry to remove.
3416 */ 3413 */
3417 for (pvp = (struct pv_entry **)&md->pvh_listx, pv = VM_MDPAGE_PVS(pg); 3414 for (pvp = (struct pv_entry **)&md->pvh_listx, pv = VM_MDPAGE_PVS(pg);
3418 pv != NULL; pvp = &pv->pv_next, pv = *pvp) 3415 pv != NULL; pvp = &pv->pv_next, pv = *pvp)
3419 if (pmap == pv->pv_pmap && va == pv->pv_va) 3416 if (pmap == pv->pv_pmap && va == pv->pv_va)
3420 break; 3417 break;
3421 3418
3422 KASSERT(pv != NULL); 3419 KASSERT(pv != NULL);
3423 3420
3424 /* 3421 /*
3425 * The page attributes are in the lower 2 bits of the first 3422 * The page attributes are in the lower 2 bits of the first
3426 * PV entry pointer. Rather than comparing the pointer address 3423 * PV entry pointer. Rather than comparing the pointer address
3427 * and branching, we just always preserve what might be there 3424 * and branching, we just always preserve what might be there
3428 * (either attribute bits or zero bits). 3425 * (either attribute bits or zero bits).
3429 */ 3426 */
3430 *pvp = (pv_entry_t)((uintptr_t)pv->pv_next | 3427 *pvp = (pv_entry_t)((uintptr_t)pv->pv_next |
3431 (((uintptr_t)*pvp) & PGA_ATTRS)); 3428 (((uintptr_t)*pvp) & PGA_ATTRS));
3432 LIST_REMOVE(pv, pv_link); 3429 LIST_REMOVE(pv, pv_link);
3433 3430
3434 if (dolock) { 3431 if (dolock) {
3435 mutex_exit(lock); 3432 mutex_exit(lock);
3436 } 3433 }
3437 3434
3438 if (opvp != NULL) { 3435 if (opvp != NULL) {
3439 *opvp = pv; 3436 *opvp = pv;
3440 } else { 3437 } else {
3441 KASSERT(tlbctx != NULL); 3438 KASSERT(tlbctx != NULL);
3442 LIST_INSERT_HEAD(&tlbctx->t_freepvq, pv, pv_link); 3439 LIST_INSERT_HEAD(&tlbctx->t_freepvq, pv, pv_link);
3443 } 3440 }
3444} 3441}
3445 3442
3446/* 3443/*
3447 * pmap_pv_page_alloc: 3444 * pmap_pv_page_alloc:
3448 * 3445 *
3449 * Allocate a page for the pv_entry pool. 3446 * Allocate a page for the pv_entry pool.
3450 */ 3447 */
3451static void * 3448static void *
3452pmap_pv_page_alloc(struct pool *pp, int flags) 3449pmap_pv_page_alloc(struct pool *pp, int flags)
3453{ 3450{
3454 struct vm_page * const pg = pmap_physpage_alloc(PGU_PVENT); 3451 struct vm_page * const pg = pmap_physpage_alloc(PGU_PVENT);
3455 if (__predict_false(pg == NULL)) { 3452 if (__predict_false(pg == NULL)) {
3456 return NULL; 3453 return NULL;
3457 } 3454 }
3458 return (void *)ALPHA_PHYS_TO_K0SEG(VM_PAGE_TO_PHYS(pg)); 3455 return (void *)ALPHA_PHYS_TO_K0SEG(VM_PAGE_TO_PHYS(pg));
3459} 3456}
3460 3457
3461/* 3458/*
3462 * pmap_pv_page_free: 3459 * pmap_pv_page_free:
3463 * 3460 *
3464 * Free a pv_entry pool page. 3461 * Free a pv_entry pool page.
3465 */ 3462 */
3466static void 3463static void
3467pmap_pv_page_free(struct pool *pp, void *v) 3464pmap_pv_page_free(struct pool *pp, void *v)
3468{ 3465{
3469 3466
3470 pmap_physpage_free(ALPHA_K0SEG_TO_PHYS((vaddr_t)v)); 3467 pmap_physpage_free(ALPHA_K0SEG_TO_PHYS((vaddr_t)v));
3471} 3468}
3472 3469
3473/******************** misc. functions ********************/ 3470/******************** misc. functions ********************/
3474 3471
3475/* 3472/*
3476 * Pages that are in-use as page table pages should never be part 3473 * Pages that are in-use as page table pages should never be part
3477 * of a UVM loan, so we'll use that field for our PT page reference 3474 * of a UVM loan, so we'll use that field for our PT page reference
3478 * count. 3475 * count.
3479 */ 3476 */
3480#define PHYSPAGE_REFCNT(pg) atomic_load_relaxed(&(pg)->loan_count) 3477#define PHYSPAGE_REFCNT(pg) atomic_load_relaxed(&(pg)->loan_count)
3481#define PHYSPAGE_REFCNT_INC(pg) atomic_inc_uint_nv(&(pg)->loan_count) 3478#define PHYSPAGE_REFCNT_INC(pg) atomic_inc_uint_nv(&(pg)->loan_count)
3482#define PHYSPAGE_REFCNT_DEC(pg) atomic_dec_uint_nv(&(pg)->loan_count) 3479#define PHYSPAGE_REFCNT_DEC(pg) atomic_dec_uint_nv(&(pg)->loan_count)
3483 3480
3484/* 3481/*
3485 * pmap_physpage_alloc: 3482 * pmap_physpage_alloc:
3486 * 3483 *
3487 * Allocate a single page from the VM system and return the 3484 * Allocate a single page from the VM system and return the
3488 * physical address for that page. 3485 * physical address for that page.
3489 */ 3486 */
3490static struct vm_page * 3487static struct vm_page *
3491pmap_physpage_alloc(int usage) 3488pmap_physpage_alloc(int usage)
3492{ 3489{
3493 struct vm_page *pg; 3490 struct vm_page *pg;
3494 3491
3495 /* 3492 /*
3496 * Don't ask for a zero'd page in the L1PT case -- we will 3493 * Don't ask for a zero'd page in the L1PT case -- we will
3497 * properly initialize it in the constructor. 3494 * properly initialize it in the constructor.
3498 */ 3495 */
3499 3496
3500 pg = uvm_pagealloc(NULL, 0, NULL, usage == PGU_L1PT ? 3497 pg = uvm_pagealloc(NULL, 0, NULL, usage == PGU_L1PT ?
3501 UVM_PGA_USERESERVE : UVM_PGA_USERESERVE|UVM_PGA_ZERO); 3498 UVM_PGA_USERESERVE : UVM_PGA_USERESERVE|UVM_PGA_ZERO);
3502 if (pg != NULL) { 3499 if (pg != NULL) {
3503 KASSERT(PHYSPAGE_REFCNT(pg) == 0); 3500 KASSERT(PHYSPAGE_REFCNT(pg) == 0);
3504 } 3501 }
3505 return pg; 3502 return pg;
3506} 3503}
3507 3504
3508/* 3505/*
3509 * pmap_physpage_free: 3506 * pmap_physpage_free:
3510 * 3507 *
3511 * Free the single page table page at the specified physical address. 3508 * Free the single page table page at the specified physical address.
3512 */ 3509 */
3513static void 3510static void
3514pmap_physpage_free(paddr_t pa) 3511pmap_physpage_free(paddr_t pa)
3515{ 3512{
3516 struct vm_page *pg; 3513 struct vm_page *pg;
3517 3514
3518 if ((pg = PHYS_TO_VM_PAGE(pa)) == NULL) 3515 if ((pg = PHYS_TO_VM_PAGE(pa)) == NULL)
3519 panic("pmap_physpage_free: bogus physical page address"); 3516 panic("pmap_physpage_free: bogus physical page address");
3520 3517
3521 KASSERT(PHYSPAGE_REFCNT(pg) == 0); 3518 KASSERT(PHYSPAGE_REFCNT(pg) == 0);
3522 3519
3523 uvm_pagefree(pg); 3520 uvm_pagefree(pg);
3524} 3521}
3525 3522
3526/* 3523/*
3527 * pmap_physpage_addref: 3524 * pmap_physpage_addref:
3528 * 3525 *
3529 * Add a reference to the specified special use page. 3526 * Add a reference to the specified special use page.
3530 */ 3527 */
3531static int 3528static int
3532pmap_physpage_addref(void *kva) 3529pmap_physpage_addref(void *kva)
3533{ 3530{
3534 struct vm_page *pg; 3531 struct vm_page *pg;
3535 paddr_t pa; 3532 paddr_t pa;
3536 3533
3537 pa = ALPHA_K0SEG_TO_PHYS(trunc_page((vaddr_t)kva)); 3534 pa = ALPHA_K0SEG_TO_PHYS(trunc_page((vaddr_t)kva));
3538 pg = PHYS_TO_VM_PAGE(pa); 3535 pg = PHYS_TO_VM_PAGE(pa);
3539 3536
3540 KASSERT(PHYSPAGE_REFCNT(pg) < UINT32_MAX); 3537 KASSERT(PHYSPAGE_REFCNT(pg) < UINT32_MAX);
3541 3538
3542 return PHYSPAGE_REFCNT_INC(pg); 3539 return PHYSPAGE_REFCNT_INC(pg);
3543} 3540}
3544 3541
3545/* 3542/*
3546 * pmap_physpage_delref: 3543 * pmap_physpage_delref:
3547 * 3544 *
3548 * Delete a reference to the specified special use page. 3545 * Delete a reference to the specified special use page.
3549 */ 3546 */
3550static int 3547static int
3551pmap_physpage_delref(void *kva) 3548pmap_physpage_delref(void *kva)
3552{ 3549{
3553 struct vm_page *pg; 3550 struct vm_page *pg;
3554 paddr_t pa; 3551 paddr_t pa;
3555 3552
3556 pa = ALPHA_K0SEG_TO_PHYS(trunc_page((vaddr_t)kva)); 3553 pa = ALPHA_K0SEG_TO_PHYS(trunc_page((vaddr_t)kva));
3557 pg = PHYS_TO_VM_PAGE(pa); 3554 pg = PHYS_TO_VM_PAGE(pa);
3558 3555
3559 KASSERT(PHYSPAGE_REFCNT(pg) != 0); 3556 KASSERT(PHYSPAGE_REFCNT(pg) != 0);
3560 3557
3561 return PHYSPAGE_REFCNT_DEC(pg); 3558 return PHYSPAGE_REFCNT_DEC(pg);
3562} 3559}
3563 3560
3564/******************** page table page management ********************/ 3561/******************** page table page management ********************/
3565 3562
3566static bool 3563static bool
3567pmap_kptpage_alloc(paddr_t *pap) 3564pmap_kptpage_alloc(paddr_t *pap)
3568{ 3565{
3569 if (uvm.page_init_done == false) { 3566 if (uvm.page_init_done == false) {
3570 /* 3567 /*
3571 * We're growing the kernel pmap early (from 3568 * We're growing the kernel pmap early (from
3572 * uvm_pageboot_alloc()). This case must 3569 * uvm_pageboot_alloc()). This case must
3573 * be handled a little differently. 3570 * be handled a little differently.
3574 */ 3571 */
3575 *pap = ALPHA_K0SEG_TO_PHYS( 3572 *pap = ALPHA_K0SEG_TO_PHYS(
3576 pmap_steal_memory(PAGE_SIZE, NULL, NULL)); 3573 pmap_steal_memory(PAGE_SIZE, NULL, NULL));
3577 return true; 3574 return true;
3578 } 3575 }
3579 3576
3580 struct vm_page * const pg = pmap_physpage_alloc(PGU_NORMAL); 3577 struct vm_page * const pg = pmap_physpage_alloc(PGU_NORMAL);
3581 if (__predict_true(pg != NULL)) { 3578 if (__predict_true(pg != NULL)) {
3582 *pap = VM_PAGE_TO_PHYS(pg); 3579 *pap = VM_PAGE_TO_PHYS(pg);
3583 return true; 3580 return true;
3584 } 3581 }
3585 return false; 3582 return false;
3586} 3583}
3587 3584
3588/* 3585/*
3589 * pmap_growkernel: [ INTERFACE ] 3586 * pmap_growkernel: [ INTERFACE ]
3590 * 3587 *
3591 * Grow the kernel address space. This is a hint from the 3588 * Grow the kernel address space. This is a hint from the
3592 * upper layer to pre-allocate more kernel PT pages. 3589 * upper layer to pre-allocate more kernel PT pages.
3593 */ 3590 */
3594vaddr_t 3591vaddr_t
3595pmap_growkernel(vaddr_t maxkvaddr) 3592pmap_growkernel(vaddr_t maxkvaddr)
3596{ 3593{
3597 struct pmap *pm; 3594 struct pmap *pm;
3598 paddr_t ptaddr; 3595 paddr_t ptaddr;
3599 pt_entry_t *l1pte, *l2pte, pte; 3596 pt_entry_t *l1pte, *l2pte, pte;
3600 pt_entry_t *lev1map; 3597 pt_entry_t *lev1map;
3601 vaddr_t va; 3598 vaddr_t va;
3602 int l1idx; 3599 int l1idx;
3603 3600
3604 rw_enter(&pmap_growkernel_lock, RW_WRITER); 3601 rw_enter(&pmap_growkernel_lock, RW_WRITER);
3605 3602
3606 if (maxkvaddr <= virtual_end) 3603 if (maxkvaddr <= virtual_end)
3607 goto out; /* we are OK */ 3604 goto out; /* we are OK */
3608 3605
3609 va = virtual_end; 3606 va = virtual_end;
3610 3607
3611 while (va < maxkvaddr) { 3608 while (va < maxkvaddr) {
3612 /* 3609 /*
3613 * If there is no valid L1 PTE (i.e. no L2 PT page), 3610 * If there is no valid L1 PTE (i.e. no L2 PT page),
3614 * allocate a new L2 PT page and insert it into the 3611 * allocate a new L2 PT page and insert it into the
3615 * L1 map. 3612 * L1 map.
3616 */ 3613 */
3617 l1pte = pmap_l1pte(kernel_lev1map, va); 3614 l1pte = pmap_l1pte(kernel_lev1map, va);
3618 if (pmap_pte_v(l1pte) == 0) { 3615 if (pmap_pte_v(l1pte) == 0) {
3619 if (!pmap_kptpage_alloc(&ptaddr)) 3616 if (!pmap_kptpage_alloc(&ptaddr))
3620 goto die; 3617 goto die;
3621 pte = (atop(ptaddr) << PG_SHIFT) | 3618 pte = (atop(ptaddr) << PG_SHIFT) |
3622 PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED; 3619 PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;
3623 *l1pte = pte; 3620 *l1pte = pte;
3624 3621
3625 l1idx = l1pte_index(va); 3622 l1idx = l1pte_index(va);
3626 3623
3627 /* Update all the user pmaps. */ 3624 /* Update all the user pmaps. */
3628 mutex_enter(&pmap_all_pmaps_lock); 3625 mutex_enter(&pmap_all_pmaps_lock);
3629 for (pm = TAILQ_FIRST(&pmap_all_pmaps); 3626 for (pm = TAILQ_FIRST(&pmap_all_pmaps);
3630 pm != NULL; pm = TAILQ_NEXT(pm, pm_list)) { 3627 pm != NULL; pm = TAILQ_NEXT(pm, pm_list)) {
3631 /* Skip the kernel pmap. */ 3628 /* Skip the kernel pmap. */
3632 if (pm == pmap_kernel()) 3629 if (pm == pmap_kernel())
3633 continue; 3630 continue;
3634 3631
3635 /* 3632 /*
3636 * Any pmaps published on the global list 3633 * Any pmaps published on the global list
3637 * should never be referencing kernel_lev1map. 3634 * should never be referencing kernel_lev1map.
3638 */ 3635 */
3639 lev1map = pmap_lev1map(pm); 3636 lev1map = pmap_lev1map(pm);
3640 KASSERT(lev1map != kernel_lev1map); 3637 KASSERT(lev1map != kernel_lev1map);
3641 3638
3642 PMAP_LOCK(pm); 3639 PMAP_LOCK(pm);
3643 lev1map[l1idx] = pte; 3640 lev1map[l1idx] = pte;
3644 PMAP_UNLOCK(pm); 3641 PMAP_UNLOCK(pm);
3645 } 3642 }
3646 mutex_exit(&pmap_all_pmaps_lock); 3643 mutex_exit(&pmap_all_pmaps_lock);
3647 } 3644 }
3648 3645
3649 /* 3646 /*
3650 * Have an L2 PT page now, add the L3 PT page. 3647 * Have an L2 PT page now, add the L3 PT page.
3651 */ 3648 */
3652 l2pte = pmap_l2pte(kernel_lev1map, va, l1pte); 3649 l2pte = pmap_l2pte(kernel_lev1map, va, l1pte);
3653 KASSERT(pmap_pte_v(l2pte) == 0); 3650 KASSERT(pmap_pte_v(l2pte) == 0);
3654 if (!pmap_kptpage_alloc(&ptaddr)) 3651 if (!pmap_kptpage_alloc(&ptaddr))
3655 goto die; 3652 goto die;
3656 *l2pte = (atop(ptaddr) << PG_SHIFT) | 3653 *l2pte = (atop(ptaddr) << PG_SHIFT) |
3657 PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED; 3654 PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;
3658 va += ALPHA_L2SEG_SIZE; 3655 va += ALPHA_L2SEG_SIZE;
3659 } 3656 }
3660 3657
3661 /* Invalidate the L1 PT cache. */ 3658 /* Invalidate the L1 PT cache. */
3662 pool_cache_invalidate(&pmap_l1pt_cache); 3659 pool_cache_invalidate(&pmap_l1pt_cache);
3663 3660
3664 virtual_end = va; 3661 virtual_end = va;
3665 3662
3666 out: 3663 out:
3667 rw_exit(&pmap_growkernel_lock); 3664 rw_exit(&pmap_growkernel_lock);
3668 3665
3669 return (virtual_end); 3666 return (virtual_end);
3670 3667
3671 die: 3668 die:
3672 panic("pmap_growkernel: out of memory"); 3669 panic("pmap_growkernel: out of memory");
3673} 3670}
3674 3671
3675/* 3672/*
3676 * pmap_l1pt_ctor: 3673 * pmap_l1pt_ctor:
3677 * 3674 *
3678 * Pool cache constructor for L1 PT pages. 3675 * Pool cache constructor for L1 PT pages.
3679 * 3676 *
3680 * Note: The growkernel lock is held across allocations 3677 * Note: The growkernel lock is held across allocations
3681 * from our pool_cache, so we don't need to acquire it 3678 * from our pool_cache, so we don't need to acquire it
3682 * ourselves. 3679 * ourselves.
3683 */ 3680 */
3684static int 3681static int
3685pmap_l1pt_ctor(void *arg, void *object, int flags) 3682pmap_l1pt_ctor(void *arg, void *object, int flags)
3686{ 3683{
3687 pt_entry_t *l1pt = object, pte; 3684 pt_entry_t *l1pt = object, pte;
3688 int i; 3685 int i;
3689 3686
3690 /* 3687 /*
3691 * Initialize the new level 1 table by zeroing the 3688 * Initialize the new level 1 table by zeroing the
3692 * user portion and copying the kernel mappings into 3689 * user portion and copying the kernel mappings into
3693 * the kernel portion. 3690 * the kernel portion.
3694 */ 3691 */
3695 for (i = 0; i < l1pte_index(VM_MIN_KERNEL_ADDRESS); i++) 3692 for (i = 0; i < l1pte_index(VM_MIN_KERNEL_ADDRESS); i++)
3696 l1pt[i] = 0; 3693 l1pt[i] = 0;
3697 3694
3698 for (i = l1pte_index(VM_MIN_KERNEL_ADDRESS); 3695 for (i = l1pte_index(VM_MIN_KERNEL_ADDRESS);
3699 i <= l1pte_index(VM_MAX_KERNEL_ADDRESS); i++) 3696 i <= l1pte_index(VM_MAX_KERNEL_ADDRESS); i++)
3700 l1pt[i] = kernel_lev1map[i]; 3697 l1pt[i] = kernel_lev1map[i];
3701 3698
3702 /* 3699 /*
3703 * Now, map the new virtual page table. NOTE: NO ASM! 3700 * Now, map the new virtual page table. NOTE: NO ASM!
3704 */ 3701 */
3705 pte = ((ALPHA_K0SEG_TO_PHYS((vaddr_t) l1pt) >> PGSHIFT) << PG_SHIFT) | 3702 pte = ((ALPHA_K0SEG_TO_PHYS((vaddr_t) l1pt) >> PGSHIFT) << PG_SHIFT) |
3706 PG_V | PG_KRE | PG_KWE; 3703 PG_V | PG_KRE | PG_KWE;
3707 l1pt[l1pte_index(VPTBASE)] = pte; 3704 l1pt[l1pte_index(VPTBASE)] = pte;
3708 3705
3709 return (0); 3706 return (0);
3710} 3707}
3711 3708
3712/* 3709/*
3713 * pmap_l1pt_alloc: 3710 * pmap_l1pt_alloc:
3714 * 3711 *
3715 * Page alloctaor for L1 PT pages. 3712 * Page alloctaor for L1 PT pages.
3716 */ 3713 */
3717static void * 3714static void *
3718pmap_l1pt_alloc(struct pool *pp, int flags) 3715pmap_l1pt_alloc(struct pool *pp, int flags)
3719{ 3716{
3720 /* 3717 /*
3721 * Attempt to allocate a free page. 3718 * Attempt to allocate a free page.
3722 */ 3719 */
3723 struct vm_page * const pg = pmap_physpage_alloc(PGU_L1PT); 3720 struct vm_page * const pg = pmap_physpage_alloc(PGU_L1PT);
3724 if (__predict_false(pg == NULL)) { 3721 if (__predict_false(pg == NULL)) {
3725 return NULL; 3722 return NULL;
3726 } 3723 }
3727 return (void *)ALPHA_PHYS_TO_K0SEG(VM_PAGE_TO_PHYS(pg)); 3724 return (void *)ALPHA_PHYS_TO_K0SEG(VM_PAGE_TO_PHYS(pg));
3728} 3725}
3729 3726
3730/* 3727/*
3731 * pmap_l1pt_free: 3728 * pmap_l1pt_free:
3732 * 3729 *
3733 * Page freer for L1 PT pages. 3730 * Page freer for L1 PT pages.
3734 */ 3731 */
3735static void 3732static void
3736pmap_l1pt_free(struct pool *pp, void *v) 3733pmap_l1pt_free(struct pool *pp, void *v)
3737{ 3734{
3738 3735
3739 pmap_physpage_free(ALPHA_K0SEG_TO_PHYS((vaddr_t) v)); 3736 pmap_physpage_free(ALPHA_K0SEG_TO_PHYS((vaddr_t) v));
3740} 3737}
3741 3738
3742/* 3739/*
3743 * pmap_ptpage_alloc: 3740 * pmap_ptpage_alloc:
3744 * 3741 *
3745 * Allocate a level 2 or level 3 page table page for a user 3742 * Allocate a level 2 or level 3 page table page for a user
3746 * pmap, and initialize the PTE that references it. 3743 * pmap, and initialize the PTE that references it.
3747 * 3744 *
3748 * Note: the pmap must already be locked. 3745 * Note: the pmap must already be locked.
3749 */ 3746 */
3750static int 3747static int
3751pmap_ptpage_alloc(pmap_t pmap, pt_entry_t * const pte, int const usage) 3748pmap_ptpage_alloc(pmap_t pmap, pt_entry_t * const pte, int const usage)
3752{ 3749{
3753 /* 3750 /*
3754 * Allocate the page table page. 3751 * Allocate the page table page.
3755 */ 3752 */
3756 struct vm_page * const pg = pmap_physpage_alloc(usage); 3753 struct vm_page * const pg = pmap_physpage_alloc(usage);
3757 if (__predict_false(pg == NULL)) { 3754 if (__predict_false(pg == NULL)) {
3758 return ENOMEM; 3755 return ENOMEM;
3759 } 3756 }
3760 3757
3761 LIST_INSERT_HEAD(&pmap->pm_ptpages, pg, pageq.list); 3758 LIST_INSERT_HEAD(&pmap->pm_ptpages, pg, pageq.list);
3762 3759
3763 /* 3760 /*
3764 * Initialize the referencing PTE. 3761 * Initialize the referencing PTE.
3765 */ 3762 */
3766 const pt_entry_t npte = ((VM_PAGE_TO_PHYS(pg) >> PGSHIFT) << PG_SHIFT) | 3763 const pt_entry_t npte = ((VM_PAGE_TO_PHYS(pg) >> PGSHIFT) << PG_SHIFT) |
3767 PG_V | PG_KRE | PG_KWE | PG_WIRED; 3764 PG_V | PG_KRE | PG_KWE | PG_WIRED;
3768 3765
3769 atomic_store_relaxed(pte, npte); 3766 atomic_store_relaxed(pte, npte);
3770 3767
3771 return (0); 3768 return (0);
3772} 3769}
3773 3770
3774/* 3771/*
3775 * pmap_ptpage_free: 3772 * pmap_ptpage_free:
3776 * 3773 *
3777 * Free the level 2 or level 3 page table page referenced 3774 * Free the level 2 or level 3 page table page referenced
3778 * be the provided PTE. 3775 * be the provided PTE.
3779 * 3776 *
3780 * Note: the pmap must already be locked. 3777 * Note: the pmap must already be locked.
3781 */ 3778 */
3782static void 3779static void
3783pmap_ptpage_free(pmap_t pmap, pt_entry_t * const pte, 3780pmap_ptpage_free(pmap_t pmap, pt_entry_t * const pte,
3784 struct pmap_tlb_context * const tlbctx) 3781 struct pmap_tlb_context * const tlbctx)
3785{ 3782{
3786 3783
3787 /* 3784 /*
3788 * Extract the physical address of the page from the PTE 3785 * Extract the physical address of the page from the PTE
3789 * and clear the entry. 3786 * and clear the entry.
3790 */ 3787 */
3791 const paddr_t ptpa = pmap_pte_pa(pte); 3788 const paddr_t ptpa = pmap_pte_pa(pte);
3792 atomic_store_relaxed(pte, PG_NV); 3789 atomic_store_relaxed(pte, PG_NV);
3793 3790
3794 struct vm_page * const pg = PHYS_TO_VM_PAGE(ptpa); 3791 struct vm_page * const pg = PHYS_TO_VM_PAGE(ptpa);
3795 KASSERT(pg != NULL); 3792 KASSERT(pg != NULL);
3796 3793
3797 KASSERT(PHYSPAGE_REFCNT(pg) == 0); 3794 KASSERT(PHYSPAGE_REFCNT(pg) == 0);
3798#ifdef DEBUG 3795#ifdef DEBUG
3799 pmap_zero_page(ptpa); 3796 pmap_zero_page(ptpa);
3800#endif 3797#endif
3801 3798
3802 LIST_REMOVE(pg, pageq.list); 3799 LIST_REMOVE(pg, pageq.list);
3803 LIST_INSERT_HEAD(&tlbctx->t_freeptq, pg, pageq.list); 3800 LIST_INSERT_HEAD(&tlbctx->t_freeptq, pg, pageq.list);
3804} 3801}
3805 3802
3806/* 3803/*
3807 * pmap_l3pt_delref: 3804 * pmap_l3pt_delref:
3808 * 3805 *
3809 * Delete a reference on a level 3 PT page. If the reference drops 3806 * Delete a reference on a level 3 PT page. If the reference drops
3810 * to zero, free it. 3807 * to zero, free it.
3811 * 3808 *
3812 * Note: the pmap must already be locked. 3809 * Note: the pmap must already be locked.
3813 */ 3810 */
3814static void 3811static void
3815pmap_l3pt_delref(pmap_t pmap, vaddr_t va, pt_entry_t *l3pte, 3812pmap_l3pt_delref(pmap_t pmap, vaddr_t va, pt_entry_t *l3pte,
3816 struct pmap_tlb_context * const tlbctx) 3813 struct pmap_tlb_context * const tlbctx)
3817{ 3814{
3818 pt_entry_t *l1pte, *l2pte; 3815 pt_entry_t *l1pte, *l2pte;
3819 pt_entry_t * const lev1map = pmap_lev1map(pmap); 3816 pt_entry_t * const lev1map = pmap_lev1map(pmap);
3820 3817
3821 l1pte = pmap_l1pte(lev1map, va); 3818 l1pte = pmap_l1pte(lev1map, va);
3822 l2pte = pmap_l2pte(lev1map, va, l1pte); 3819 l2pte = pmap_l2pte(lev1map, va, l1pte);
3823 3820
3824#ifdef DIAGNOSTIC 3821#ifdef DIAGNOSTIC
3825 if (pmap == pmap_kernel()) 3822 if (pmap == pmap_kernel())
3826 panic("pmap_l3pt_delref: kernel pmap"); 3823 panic("pmap_l3pt_delref: kernel pmap");
3827#endif 3824#endif
3828 3825
3829 if (pmap_physpage_delref(l3pte) == 0) { 3826 if (pmap_physpage_delref(l3pte) == 0) {
3830 /* 3827 /*
3831 * No more mappings; we can free the level 3 table. 3828 * No more mappings; we can free the level 3 table.
3832 */ 3829 */
3833#ifdef DEBUG 3830#ifdef DEBUG
3834 if (pmapdebug & PDB_PTPAGE) 3831 if (pmapdebug & PDB_PTPAGE)
3835 printf("pmap_l3pt_delref: freeing level 3 table at " 3832 printf("pmap_l3pt_delref: freeing level 3 table at "
3836 "0x%lx\n", pmap_pte_pa(l2pte)); 3833 "0x%lx\n", pmap_pte_pa(l2pte));
3837#endif 3834#endif
3838 /* 3835 /*
3839 * You can pass NULL if you know the last refrence won't 3836 * You can pass NULL if you know the last refrence won't
3840 * be dropped. 3837 * be dropped.
3841 */ 3838 */
3842 KASSERT(tlbctx != NULL); 3839 KASSERT(tlbctx != NULL);
3843 pmap_ptpage_free(pmap, l2pte, tlbctx); 3840 pmap_ptpage_free(pmap, l2pte, tlbctx);
3844 3841
3845 /* 3842 /*
3846 * We've freed a level 3 table, so we must invalidate 3843 * We've freed a level 3 table, so we must invalidate
3847 * any now-stale TLB entries for the corresponding VPT 3844 * any now-stale TLB entries for the corresponding VPT
3848 * VA range. Easiest way to guarantee this is to hit 3845 * VA range. Easiest way to guarantee this is to hit
3849 * all of the user TLB entries. 3846 * all of the user TLB entries.
3850 */ 3847 */
3851 pmap_tlb_shootdown_all_user(pmap, PG_V, tlbctx); 3848 pmap_tlb_shootdown_all_user(pmap, PG_V, tlbctx);
3852 3849
3853 /* 3850 /*
3854 * We've freed a level 3 table, so delete the reference 3851 * We've freed a level 3 table, so delete the reference
3855 * on the level 2 table. 3852 * on the level 2 table.
3856 */ 3853 */
3857 pmap_l2pt_delref(pmap, l1pte, l2pte, tlbctx); 3854 pmap_l2pt_delref(pmap, l1pte, l2pte, tlbctx);
3858 } 3855 }
3859} 3856}
3860 3857
3861/* 3858/*
3862 * pmap_l2pt_delref: 3859 * pmap_l2pt_delref:
3863 * 3860 *
3864 * Delete a reference on a level 2 PT page. If the reference drops 3861 * Delete a reference on a level 2 PT page. If the reference drops
3865 * to zero, free it. 3862 * to zero, free it.
3866 * 3863 *
3867 * Note: the pmap must already be locked. 3864 * Note: the pmap must already be locked.
3868 */ 3865 */
3869static void 3866static void
3870pmap_l2pt_delref(pmap_t pmap, pt_entry_t *l1pte, pt_entry_t *l2pte, 3867pmap_l2pt_delref(pmap_t pmap, pt_entry_t *l1pte, pt_entry_t *l2pte,
3871 struct pmap_tlb_context * const tlbctx) 3868 struct pmap_tlb_context * const tlbctx)
3872{ 3869{
3873 3870
3874#ifdef DIAGNOSTIC 3871#ifdef DIAGNOSTIC
3875 if (pmap == pmap_kernel()) 3872 if (pmap == pmap_kernel())
3876 panic("pmap_l2pt_delref: kernel pmap"); 3873 panic("pmap_l2pt_delref: kernel pmap");
3877#endif 3874#endif
3878 3875
3879 if (pmap_physpage_delref(l2pte) == 0) { 3876 if (pmap_physpage_delref(l2pte) == 0) {
3880 /* 3877 /*
3881 * No more mappings in this segment; we can free the 3878 * No more mappings in this segment; we can free the
3882 * level 2 table. 3879 * level 2 table.
3883 */ 3880 */
3884#ifdef DEBUG 3881#ifdef DEBUG
3885 if (pmapdebug & PDB_PTPAGE) 3882 if (pmapdebug & PDB_PTPAGE)
3886 printf("pmap_l2pt_delref: freeing level 2 table at " 3883 printf("pmap_l2pt_delref: freeing level 2 table at "
3887 "0x%lx\n", pmap_pte_pa(l1pte)); 3884 "0x%lx\n", pmap_pte_pa(l1pte));
3888#endif 3885#endif
3889 /* 3886 /*
3890 * You can pass NULL if you know the last refrence won't 3887 * You can pass NULL if you know the last refrence won't
3891 * be dropped. 3888 * be dropped.
3892 */ 3889 */
3893 KASSERT(tlbctx != NULL); 3890 KASSERT(tlbctx != NULL);
3894 pmap_ptpage_free(pmap, l1pte, tlbctx); 3891 pmap_ptpage_free(pmap, l1pte, tlbctx);
3895 3892
3896 /* 3893 /*
3897 * We've freed a level 2 table, so we must invalidate 3894 * We've freed a level 2 table, so we must invalidate
3898 * any now-stale TLB entries for the corresponding VPT 3895 * any now-stale TLB entries for the corresponding VPT
3899 * VA range. Easiest way to guarantee this is to hit 3896 * VA range. Easiest way to guarantee this is to hit
3900 * all of the user TLB entries. 3897 * all of the user TLB entries.
3901 */ 3898 */
3902 pmap_tlb_shootdown_all_user(pmap, PG_V, tlbctx); 3899 pmap_tlb_shootdown_all_user(pmap, PG_V, tlbctx);
3903 3900
3904 /* 3901 /*
3905 * We've freed a level 2 table, so delete the reference 3902 * We've freed a level 2 table, so delete the reference
3906 * on the level 1 table. 3903 * on the level 1 table.
3907 */ 3904 */
3908 pmap_l1pt_delref(pmap, l1pte); 3905 pmap_l1pt_delref(pmap, l1pte);
3909 } 3906 }
3910} 3907}
3911 3908
3912/* 3909/*
3913 * pmap_l1pt_delref: 3910 * pmap_l1pt_delref:
3914 * 3911 *
3915 * Delete a reference on a level 1 PT page. 3912 * Delete a reference on a level 1 PT page.
3916 */ 3913 */
3917static void 3914static void
3918pmap_l1pt_delref(pmap_t pmap, pt_entry_t *l1pte) 3915pmap_l1pt_delref(pmap_t pmap, pt_entry_t *l1pte)
3919{ 3916{
3920 3917
3921 KASSERT(pmap != pmap_kernel()); 3918 KASSERT(pmap != pmap_kernel());
3922 3919
3923 (void)pmap_physpage_delref(l1pte); 3920 (void)pmap_physpage_delref(l1pte);
3924} 3921}
3925 3922
3926/******************** Address Space Number management ********************/ 3923/******************** Address Space Number management ********************/
3927 3924
3928/* 3925/*
3929 * pmap_asn_alloc: 3926 * pmap_asn_alloc:
3930 * 3927 *
3931 * Allocate and assign an ASN to the specified pmap. 3928 * Allocate and assign an ASN to the specified pmap.
3932 * 3929 *
3933 * Note: the pmap must already be locked. This may be called from 3930 * Note: the pmap must already be locked. This may be called from
3934 * an interprocessor interrupt, and in that case, the sender of 3931 * an interprocessor interrupt, and in that case, the sender of
3935 * the IPI has the pmap lock. 3932 * the IPI has the pmap lock.
3936 */ 3933 */
3937static u_int 3934static u_int
3938pmap_asn_alloc(pmap_t const pmap, struct cpu_info * const ci) 3935pmap_asn_alloc(pmap_t const pmap, struct cpu_info * const ci)
3939{ 3936{
3940 3937
3941#ifdef DEBUG 3938#ifdef DEBUG
3942 if (pmapdebug & (PDB_FOLLOW|PDB_ASN)) 3939 if (pmapdebug & (PDB_FOLLOW|PDB_ASN))
3943 printf("pmap_asn_alloc(%p)\n", pmap); 3940 printf("pmap_asn_alloc(%p)\n", pmap);
3944#endif 3941#endif
3945 3942
3946 KASSERT(pmap != pmap_kernel()); 3943 KASSERT(pmap != pmap_kernel());
3947 KASSERT(pmap->pm_percpu[ci->ci_cpuid].pmc_lev1map != kernel_lev1map); 3944 KASSERT(pmap->pm_percpu[ci->ci_cpuid].pmc_lev1map != kernel_lev1map);
3948 KASSERT(kpreempt_disabled()); 3945 KASSERT(kpreempt_disabled());
3949 3946
3950 /* No work to do if the the CPU does not implement ASNs. */ 3947 /* No work to do if the the CPU does not implement ASNs. */
3951 if (pmap_max_asn == 0) 3948 if (pmap_max_asn == 0)
3952 return 0; 3949 return 0;
3953 3950
3954 struct pmap_percpu * const pmc = &pmap->pm_percpu[ci->ci_cpuid]; 3951 struct pmap_percpu * const pmc = &pmap->pm_percpu[ci->ci_cpuid];
3955 3952
3956 /* 3953 /*
3957 * Hopefully, we can continue using the one we have... 3954 * Hopefully, we can continue using the one we have...
3958 * 3955 *
3959 * N.B. the generation check will fail the first time 3956 * N.B. the generation check will fail the first time
3960 * any pmap is activated on a given CPU, because we start 3957 * any pmap is activated on a given CPU, because we start
3961 * the generation counter at 1, but initialize pmaps with 3958 * the generation counter at 1, but initialize pmaps with
3962 * 0; this forces the first ASN allocation to occur. 3959 * 0; this forces the first ASN allocation to occur.
3963 */ 3960 */
3964 if (pmc->pmc_asngen == ci->ci_asn_gen) { 3961 if (pmc->pmc_asngen == ci->ci_asn_gen) {
3965#ifdef DEBUG 3962#ifdef DEBUG
3966 if (pmapdebug & PDB_ASN) 3963 if (pmapdebug & PDB_ASN)
3967 printf("pmap_asn_alloc: same generation, keeping %u\n", 3964 printf("pmap_asn_alloc: same generation, keeping %u\n",
3968 pmc->pmc_asn); 3965 pmc->pmc_asn);
3969#endif 3966#endif
3970 TLB_COUNT(asn_reuse); 3967 TLB_COUNT(asn_reuse);
3971 return pmc->pmc_asn; 3968 return pmc->pmc_asn;
3972 } 3969 }
3973 3970
3974 /* 3971 /*
3975 * Need to assign a new ASN. Grab the next one, incrementing 3972 * Need to assign a new ASN. Grab the next one, incrementing
3976 * the generation number if we have to. 3973 * the generation number if we have to.
3977 */ 3974 */
3978 if (ci->ci_next_asn > pmap_max_asn) { 3975 if (ci->ci_next_asn > pmap_max_asn) {
3979 /* 3976 /*
3980 * Invalidate all non-PG_ASM TLB entries and the 3977 * Invalidate all non-PG_ASM TLB entries and the
3981 * I-cache, and bump the generation number. 3978 * I-cache, and bump the generation number.
3982 */ 3979 */
3983 ALPHA_TBIAP(); 3980 ALPHA_TBIAP();
3984 alpha_pal_imb(); 3981 alpha_pal_imb();
3985 3982
3986 ci->ci_next_asn = PMAP_ASN_FIRST_USER; 3983 ci->ci_next_asn = PMAP_ASN_FIRST_USER;
3987 ci->ci_asn_gen++; 3984 ci->ci_asn_gen++;
3988 TLB_COUNT(asn_newgen); 3985 TLB_COUNT(asn_newgen);
3989 3986
3990 /* 3987 /*
3991 * Make sure the generation number doesn't wrap. We could 3988 * Make sure the generation number doesn't wrap. We could
3992 * handle this scenario by traversing all of the pmaps, 3989 * handle this scenario by traversing all of the pmaps,
3993 * and invalidating the generation number on those which 3990 * and invalidating the generation number on those which
3994 * are not currently in use by this processor. 3991 * are not currently in use by this processor.
3995 * 3992 *
3996 * However... considering that we're using an unsigned 64-bit 3993 * However... considering that we're using an unsigned 64-bit
3997 * integer for generation numbers, on non-ASN CPUs, we won't 3994 * integer for generation numbers, on non-ASN CPUs, we won't
3998 * wrap for approximately 75 billion years on a 128-ASN CPU 3995 * wrap for approximately 75 billion years on a 128-ASN CPU
3999 * (assuming 1000 switch * operations per second). 3996 * (assuming 1000 switch * operations per second).
4000 * 3997 *
4001 * So, we don't bother. 3998 * So, we don't bother.
4002 */ 3999 */
4003 KASSERT(ci->ci_asn_gen != PMAP_ASNGEN_INVALID); 4000 KASSERT(ci->ci_asn_gen != PMAP_ASNGEN_INVALID);
4004#ifdef DEBUG 4001#ifdef DEBUG
4005 if (pmapdebug & PDB_ASN) 4002 if (pmapdebug & PDB_ASN)
4006 printf("pmap_asn_alloc: generation bumped to %lu\n", 4003 printf("pmap_asn_alloc: generation bumped to %lu\n",
4007 ci->ci_asn_ge); 4004 ci->ci_asn_gen);
4008#endif 4005#endif
4009 } 4006 }
4010 4007
4011 /* 4008 /*
4012 * Assign the new ASN and validate the generation number. 4009 * Assign the new ASN and validate the generation number.
4013 */ 4010 */
4014 pmc->pmc_asn = ci->ci_next_asn++; 4011 pmc->pmc_asn = ci->ci_next_asn++;
4015 pmc->pmc_asngen = ci->ci_asn_gen; 4012 pmc->pmc_asngen = ci->ci_asn_gen;
4016 TLB_COUNT(asn_assign); 4013 TLB_COUNT(asn_assign);
4017 4014
4018 /* 4015 /*
4019 * We have a new ASN, so we can skip any pending I-stream sync 4016 * We have a new ASN, so we can skip any pending I-stream sync
4020 * on the way back out to user space. 4017 * on the way back out to user space.
4021 */ 4018 */
4022 pmc->pmc_needisync = 0; 4019 pmc->pmc_needisync = 0;
4023 4020
4024#ifdef DEBUG 4021#ifdef DEBUG
4025 if (pmapdebug & PDB_ASN) 4022 if (pmapdebug & PDB_ASN)
4026 printf("pmap_asn_alloc: assigning %u to pmap %p\n", 4023 printf("pmap_asn_alloc: assigning %u to pmap %p\n",
4027 pmc->pmc_asn, pmap); 4024 pmc->pmc_asn, pmap);
4028#endif 4025#endif
4029 return pmc->pmc_asn; 4026 return pmc->pmc_asn;
4030} 4027}