Sun May 30 01:41:45 2021 UTC ()
Track the PT pages allocated to a pmap in the pmap itself.


(thorpej)
diff -r1.283 -r1.284 src/sys/arch/alpha/alpha/pmap.c
diff -r1.89 -r1.90 src/sys/arch/alpha/include/pmap.h

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

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

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

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