Sun May 30 00:34:27 2021 UTC ()
Define a pmap_pagelist LIST_HEAD and use it where we used ad hoc LIST_HEADs
of vm_page structures.  Define and use a generic routine to free such a list
back to UVM.

In pmap_remove_internal(), KASSERT that no PT pages are queued up to be
freed when removing mappings from the kernel pmap.


(thorpej)
diff -r1.281 -r1.282 src/sys/arch/alpha/alpha/pmap.c
diff -r1.88 -r1.89 src/sys/arch/alpha/include/pmap.h

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

--- src/sys/arch/alpha/alpha/pmap.c 2021/05/29 23:27:22 1.281
+++ src/sys/arch/alpha/alpha/pmap.c 2021/05/30 00:34:27 1.282
@@ -1,2722 +1,2733 @@ @@ -1,2722 +1,2733 @@
1/* $NetBSD: pmap.c,v 1.281 2021/05/29 23:27:22 thorpej Exp $ */ 1/* $NetBSD: pmap.c,v 1.282 2021/05/30 00:34:27 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.281 2021/05/29 23:27:22 thorpej Exp $"); 138__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.282 2021/05/30 00:34:27 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
 436 * the system.
 437 */
 438static void
 439pmap_pagelist_free(struct pmap_pagelist * const list)
 440{
 441 struct vm_page *pg;
 442
 443 while ((pg = LIST_FIRST(list)) != NULL) {
 444 LIST_REMOVE(pg, pageq.list);
 445 uvm_pagefree(pg);
 446 }
 447}
 448
 449/*
435 * TLB management. 450 * TLB management.
436 * 451 *
437 * TLB invalidations need to be performed on local and remote CPUs 452 * TLB invalidations need to be performed on local and remote CPUs
438 * whenever parts of the PTE that the hardware or PALcode understands 453 * whenever parts of the PTE that the hardware or PALcode understands
439 * changes. In order amortize the cost of these operations, we will 454 * changes. In order amortize the cost of these operations, we will
440 * queue up to 8 addresses to invalidate in a batch. Any more than 455 * queue up to 8 addresses to invalidate in a batch. Any more than
441 * that, and we will hit the entire TLB. 456 * that, and we will hit the entire TLB.
442 * 457 *
443 * Some things that add complexity: 458 * Some things that add complexity:
444 * 459 *
445 * ==> 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
446 * address spaace. We can only invalidate TLB entries for the current 461 * address spaace. We can only invalidate TLB entries for the current
447 * address space, so when asked to invalidate a VA for the non-current 462 * address space, so when asked to invalidate a VA for the non-current
448 * pmap on a given CPU, we simply invalidate the ASN for that pmap,CPU 463 * pmap on a given CPU, we simply invalidate the ASN for that pmap,CPU
449 * tuple so that new one is allocated on the next activation on that 464 * tuple so that new one is allocated on the next activation on that
450 * CPU. N.B. that for CPUs that don't implement ASNs, SWPCTX does all 465 * CPU. N.B. that for CPUs that don't implement ASNs, SWPCTX does all
451 * the work necessary, so we can skip some work in the pmap module 466 * the work necessary, so we can skip some work in the pmap module
452 * itself. 467 * itself.
453 * 468 *
454 * 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
455 * bit in pmap::pm_cpus, indicating that it potentially has valid 470 * bit in pmap::pm_cpus, indicating that it potentially has valid
456 * 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
457 * determine which remote CPUs need to be notified of invalidations. 472 * determine which remote CPUs need to be notified of invalidations.
458 * 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.
459 * 474 *
460 * In order to serialize with activating an address space on a 475 * In order to serialize with activating an address space on a
461 * given CPU (that we can reliably send notifications only to 476 * given CPU (that we can reliably send notifications only to
462 * relevant remote CPUs), we acquire the pmap lock in pmap_activate() 477 * relevant remote CPUs), we acquire the pmap lock in pmap_activate()
463 * and also hold the lock while remote shootdowns take place. 478 * and also hold the lock while remote shootdowns take place.
464 * 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
465 * 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
466 * in pmap_activate() for the kernel pmap. 481 * in pmap_activate() for the kernel pmap.
467 * 482 *
468 * ==> P->V operations (e.g. pmap_page_protect()) may require sending 483 * ==> P->V operations (e.g. pmap_page_protect()) may require sending
469 * invalidations for multiple address spaces. We only track one 484 * invalidations for multiple address spaces. We only track one
470 * 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
471 * 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
472 * 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,
473 * so all CPUs will get the notification, and they check when 488 * so all CPUs will get the notification, and they check when
474 * processing the notification if the pmap is current on that CPU. 489 * processing the notification if the pmap is current on that CPU.
475 * 490 *
476 * Invalidation information is gathered into a pmap_tlb_context structure 491 * Invalidation information is gathered into a pmap_tlb_context structure
477 * that includes room for 8 VAs, the pmap the VAs belong to, a bitmap of 492 * that includes room for 8 VAs, the pmap the VAs belong to, a bitmap of
478 * CPUs to be notified, and a list for PT pages that are freed during 493 * CPUs to be notified, and a list for PT pages that are freed during
479 * removal off mappings. The number of valid addresses in the list as 494 * removal off mappings. The number of valid addresses in the list as
480 * well as flags are sqeezed into the lower bits of the first two VAs. 495 * well as flags are sqeezed into the lower bits of the first two VAs.
481 * Storage for this structure is allocated on the stack. We need to be 496 * Storage for this structure is allocated on the stack. We need to be
482 * careful to keep the size of this struture under control. 497 * careful to keep the size of this struture under control.
483 * 498 *
484 * When notifying remote CPUs, we acquire the tlb_lock (which also 499 * When notifying remote CPUs, we acquire the tlb_lock (which also
485 * blocks IPIs), record the pointer to our context structure, set a 500 * blocks IPIs), record the pointer to our context structure, set a
486 * global bitmap off CPUs to be notified, and then send the IPIs to 501 * global bitmap off CPUs to be notified, and then send the IPIs to
487 * each victim. While the other CPUs are in-flight, we then perform 502 * each victim. While the other CPUs are in-flight, we then perform
488 * any invalidations necessary on the local CPU. Once that is done, 503 * any invalidations necessary on the local CPU. Once that is done,
489 * 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
490 * 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
491 * method reduces cache line contention during pocessing. 506 * method reduces cache line contention during pocessing.
492 * 507 *
493 * When removing mappings in user pmaps, this implemention frees page 508 * When removing mappings in user pmaps, this implemention frees page
494 * 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.
495 * 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
496 * CPU might hold for the respective recursive VPT mappings. This must 511 * CPU might hold for the respective recursive VPT mappings. This must
497 * be done whenever an L1 or L2 PTE is invalidated. Until these VPT 512 * be done whenever an L1 or L2 PTE is invalidated. Until these VPT
498 * translations are invalidated, the PT pages must not be reused. For 513 * translations are invalidated, the PT pages must not be reused. For
499 * this reason, we keep a list of freed PT pages in the context stucture 514 * this reason, we keep a list of freed PT pages in the context stucture
500 * and drain them off once all invalidations are complete. 515 * and drain them off once all invalidations are complete.
501 * 516 *
502 * 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
503 * window size (defined as 64KB on alpha in <machine/vmparam.h>). 518 * window size (defined as 64KB on alpha in <machine/vmparam.h>).
504 */ 519 */
505 520
506#define TLB_CTX_MAXVA 8 521#define TLB_CTX_MAXVA 8
507#define TLB_CTX_ALLVA PAGE_MASK 522#define TLB_CTX_ALLVA PAGE_MASK
508 523
509#define TLB_CTX_F_ASM __BIT(0) 524#define TLB_CTX_F_ASM __BIT(0)
510#define TLB_CTX_F_IMB __BIT(1) 525#define TLB_CTX_F_IMB __BIT(1)
511#define TLB_CTX_F_KIMB __BIT(2) 526#define TLB_CTX_F_KIMB __BIT(2)
512#define TLB_CTX_F_PV __BIT(3) 527#define TLB_CTX_F_PV __BIT(3)
513#define TLB_CTX_F_MULTI __BIT(4) 528#define TLB_CTX_F_MULTI __BIT(4)
514 529
515#define TLB_CTX_COUNT(ctx) ((ctx)->t_addrdata[0] & PAGE_MASK) 530#define TLB_CTX_COUNT(ctx) ((ctx)->t_addrdata[0] & PAGE_MASK)
516#define TLB_CTX_INC_COUNT(ctx) (ctx)->t_addrdata[0]++ 531#define TLB_CTX_INC_COUNT(ctx) (ctx)->t_addrdata[0]++
517#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
518 533
519#define TLB_CTX_FLAGS(ctx) ((ctx)->t_addrdata[1] & PAGE_MASK) 534#define TLB_CTX_FLAGS(ctx) ((ctx)->t_addrdata[1] & PAGE_MASK)
520#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)
521 536
522#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)
523#define TLB_CTX_SETVA(ctx, i, va) \ 538#define TLB_CTX_SETVA(ctx, i, va) \
524 (ctx)->t_addrdata[(i)] = (va) | ((ctx)->t_addrdata[(i)] & PAGE_MASK) 539 (ctx)->t_addrdata[(i)] = (va) | ((ctx)->t_addrdata[(i)] & PAGE_MASK)
525 540
526struct pmap_tlb_context { 541struct pmap_tlb_context {
527 uintptr_t t_addrdata[TLB_CTX_MAXVA]; 542 uintptr_t t_addrdata[TLB_CTX_MAXVA];
528 pmap_t t_pmap; 543 pmap_t t_pmap;
529 LIST_HEAD(, vm_page) t_freeptq; 544 struct pmap_pagelist t_freeptq;
530}; 545};
531 546
532static struct { 547static struct {
533 kmutex_t lock; 548 kmutex_t lock;
534 struct evcnt events; 549 struct evcnt events;
535} tlb_shootdown __cacheline_aligned; 550} tlb_shootdown __cacheline_aligned;
536#define tlb_lock tlb_shootdown.lock 551#define tlb_lock tlb_shootdown.lock
537#define tlb_evcnt tlb_shootdown.events 552#define tlb_evcnt tlb_shootdown.events
538#if defined(MULTIPROCESSOR) 553#if defined(MULTIPROCESSOR)
539static const struct pmap_tlb_context *tlb_context __cacheline_aligned; 554static const struct pmap_tlb_context *tlb_context __cacheline_aligned;
540static unsigned long tlb_pending __cacheline_aligned; 555static unsigned long tlb_pending __cacheline_aligned;
541#endif /* MULTIPROCESSOR */ 556#endif /* MULTIPROCESSOR */
542 557
543#if defined(TLB_STATS) 558#if defined(TLB_STATS)
544#define TLB_COUNT_DECL(cnt) static struct evcnt tlb_stat_##cnt 559#define TLB_COUNT_DECL(cnt) static struct evcnt tlb_stat_##cnt
545#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)
546#define TLB_COUNT_ATTACH(cnt) \ 561#define TLB_COUNT_ATTACH(cnt) \
547 evcnt_attach_dynamic_nozero(&tlb_stat_##cnt, EVCNT_TYPE_MISC, \ 562 evcnt_attach_dynamic_nozero(&tlb_stat_##cnt, EVCNT_TYPE_MISC, \
548 NULL, "TLB", #cnt) 563 NULL, "TLB", #cnt)
549 564
550TLB_COUNT_DECL(invalidate_multi_tbia); 565TLB_COUNT_DECL(invalidate_multi_tbia);
551TLB_COUNT_DECL(invalidate_multi_tbiap); 566TLB_COUNT_DECL(invalidate_multi_tbiap);
552TLB_COUNT_DECL(invalidate_multi_imb); 567TLB_COUNT_DECL(invalidate_multi_imb);
553 568
554TLB_COUNT_DECL(invalidate_kern_tbia); 569TLB_COUNT_DECL(invalidate_kern_tbia);
555TLB_COUNT_DECL(invalidate_kern_tbis); 570TLB_COUNT_DECL(invalidate_kern_tbis);
556TLB_COUNT_DECL(invalidate_kern_imb); 571TLB_COUNT_DECL(invalidate_kern_imb);
557 572
558TLB_COUNT_DECL(invalidate_user_not_current); 573TLB_COUNT_DECL(invalidate_user_not_current);
559TLB_COUNT_DECL(invalidate_user_lazy_imb); 574TLB_COUNT_DECL(invalidate_user_lazy_imb);
560TLB_COUNT_DECL(invalidate_user_tbiap); 575TLB_COUNT_DECL(invalidate_user_tbiap);
561TLB_COUNT_DECL(invalidate_user_tbis); 576TLB_COUNT_DECL(invalidate_user_tbis);
562 577
563TLB_COUNT_DECL(shootdown_kernel); 578TLB_COUNT_DECL(shootdown_kernel);
564TLB_COUNT_DECL(shootdown_user); 579TLB_COUNT_DECL(shootdown_user);
565TLB_COUNT_DECL(shootdown_imb); 580TLB_COUNT_DECL(shootdown_imb);
566TLB_COUNT_DECL(shootdown_kimb); 581TLB_COUNT_DECL(shootdown_kimb);
567TLB_COUNT_DECL(shootdown_overflow); 582TLB_COUNT_DECL(shootdown_overflow);
568 583
569TLB_COUNT_DECL(shootdown_all_user); 584TLB_COUNT_DECL(shootdown_all_user);
570TLB_COUNT_DECL(shootdown_all_user_imb); 585TLB_COUNT_DECL(shootdown_all_user_imb);
571 586
572TLB_COUNT_DECL(shootdown_pv); 587TLB_COUNT_DECL(shootdown_pv);
573TLB_COUNT_DECL(shootdown_pv_multi); 588TLB_COUNT_DECL(shootdown_pv_multi);
574 589
575TLB_COUNT_DECL(shootnow_over_notify); 590TLB_COUNT_DECL(shootnow_over_notify);
576TLB_COUNT_DECL(shootnow_remote); 591TLB_COUNT_DECL(shootnow_remote);
577 592
578TLB_COUNT_DECL(reason_remove_kernel); 593TLB_COUNT_DECL(reason_remove_kernel);
579TLB_COUNT_DECL(reason_remove_user); 594TLB_COUNT_DECL(reason_remove_user);
580TLB_COUNT_DECL(reason_page_protect_read); 595TLB_COUNT_DECL(reason_page_protect_read);
581TLB_COUNT_DECL(reason_page_protect_none); 596TLB_COUNT_DECL(reason_page_protect_none);
582TLB_COUNT_DECL(reason_protect); 597TLB_COUNT_DECL(reason_protect);
583TLB_COUNT_DECL(reason_enter_kernel); 598TLB_COUNT_DECL(reason_enter_kernel);
584TLB_COUNT_DECL(reason_enter_user); 599TLB_COUNT_DECL(reason_enter_user);
585TLB_COUNT_DECL(reason_kenter); 600TLB_COUNT_DECL(reason_kenter);
586TLB_COUNT_DECL(reason_enter_l2pt_delref); 601TLB_COUNT_DECL(reason_enter_l2pt_delref);
587TLB_COUNT_DECL(reason_enter_l3pt_delref); 602TLB_COUNT_DECL(reason_enter_l3pt_delref);
588TLB_COUNT_DECL(reason_kremove); 603TLB_COUNT_DECL(reason_kremove);
589TLB_COUNT_DECL(reason_clear_modify); 604TLB_COUNT_DECL(reason_clear_modify);
590TLB_COUNT_DECL(reason_clear_reference); 605TLB_COUNT_DECL(reason_clear_reference);
591TLB_COUNT_DECL(reason_emulate_reference); 606TLB_COUNT_DECL(reason_emulate_reference);
592 607
593TLB_COUNT_DECL(asn_reuse); 608TLB_COUNT_DECL(asn_reuse);
594TLB_COUNT_DECL(asn_newgen); 609TLB_COUNT_DECL(asn_newgen);
595TLB_COUNT_DECL(asn_assign); 610TLB_COUNT_DECL(asn_assign);
596 611
597TLB_COUNT_DECL(activate_both_change); 612TLB_COUNT_DECL(activate_both_change);
598TLB_COUNT_DECL(activate_asn_change); 613TLB_COUNT_DECL(activate_asn_change);
599TLB_COUNT_DECL(activate_ptbr_change); 614TLB_COUNT_DECL(activate_ptbr_change);
600TLB_COUNT_DECL(activate_swpctx); 615TLB_COUNT_DECL(activate_swpctx);
601TLB_COUNT_DECL(activate_skip_swpctx); 616TLB_COUNT_DECL(activate_skip_swpctx);
602 617
603#else /* ! TLB_STATS */ 618#else /* ! TLB_STATS */
604#define TLB_COUNT(cnt) __nothing 619#define TLB_COUNT(cnt) __nothing
605#define TLB_COUNT_ATTACH(cnt) __nothing 620#define TLB_COUNT_ATTACH(cnt) __nothing
606#endif /* TLB_STATS */ 621#endif /* TLB_STATS */
607 622
608static void 623static void
609pmap_tlb_init(void) 624pmap_tlb_init(void)
610{ 625{
611 /* mutex is initialized in pmap_bootstrap(). */ 626 /* mutex is initialized in pmap_bootstrap(). */
612 627
613 evcnt_attach_dynamic_nozero(&tlb_evcnt, EVCNT_TYPE_MISC, 628 evcnt_attach_dynamic_nozero(&tlb_evcnt, EVCNT_TYPE_MISC,
614 NULL, "TLB", "shootdown"); 629 NULL, "TLB", "shootdown");
615 630
616 TLB_COUNT_ATTACH(invalidate_multi_tbia); 631 TLB_COUNT_ATTACH(invalidate_multi_tbia);
617 TLB_COUNT_ATTACH(invalidate_multi_tbiap); 632 TLB_COUNT_ATTACH(invalidate_multi_tbiap);
618 TLB_COUNT_ATTACH(invalidate_multi_imb); 633 TLB_COUNT_ATTACH(invalidate_multi_imb);
619 634
620 TLB_COUNT_ATTACH(invalidate_kern_tbia); 635 TLB_COUNT_ATTACH(invalidate_kern_tbia);
621 TLB_COUNT_ATTACH(invalidate_kern_tbis); 636 TLB_COUNT_ATTACH(invalidate_kern_tbis);
622 TLB_COUNT_ATTACH(invalidate_kern_imb); 637 TLB_COUNT_ATTACH(invalidate_kern_imb);
623 638
624 TLB_COUNT_ATTACH(invalidate_user_not_current); 639 TLB_COUNT_ATTACH(invalidate_user_not_current);
625 TLB_COUNT_ATTACH(invalidate_user_lazy_imb); 640 TLB_COUNT_ATTACH(invalidate_user_lazy_imb);
626 TLB_COUNT_ATTACH(invalidate_user_tbiap); 641 TLB_COUNT_ATTACH(invalidate_user_tbiap);
627 TLB_COUNT_ATTACH(invalidate_user_tbis); 642 TLB_COUNT_ATTACH(invalidate_user_tbis);
628 643
629 TLB_COUNT_ATTACH(shootdown_kernel); 644 TLB_COUNT_ATTACH(shootdown_kernel);
630 TLB_COUNT_ATTACH(shootdown_user); 645 TLB_COUNT_ATTACH(shootdown_user);
631 TLB_COUNT_ATTACH(shootdown_imb); 646 TLB_COUNT_ATTACH(shootdown_imb);
632 TLB_COUNT_ATTACH(shootdown_kimb); 647 TLB_COUNT_ATTACH(shootdown_kimb);
633 TLB_COUNT_ATTACH(shootdown_overflow); 648 TLB_COUNT_ATTACH(shootdown_overflow);
634 649
635 TLB_COUNT_ATTACH(shootdown_all_user); 650 TLB_COUNT_ATTACH(shootdown_all_user);
636 TLB_COUNT_ATTACH(shootdown_all_user_imb); 651 TLB_COUNT_ATTACH(shootdown_all_user_imb);
637 652
638 TLB_COUNT_ATTACH(shootdown_pv); 653 TLB_COUNT_ATTACH(shootdown_pv);
639 TLB_COUNT_ATTACH(shootdown_pv_multi); 654 TLB_COUNT_ATTACH(shootdown_pv_multi);
640 655
641 TLB_COUNT_ATTACH(shootnow_over_notify); 656 TLB_COUNT_ATTACH(shootnow_over_notify);
642 TLB_COUNT_ATTACH(shootnow_remote); 657 TLB_COUNT_ATTACH(shootnow_remote);
643 658
644 TLB_COUNT_ATTACH(reason_remove_kernel); 659 TLB_COUNT_ATTACH(reason_remove_kernel);
645 TLB_COUNT_ATTACH(reason_remove_user); 660 TLB_COUNT_ATTACH(reason_remove_user);
646 TLB_COUNT_ATTACH(reason_page_protect_read); 661 TLB_COUNT_ATTACH(reason_page_protect_read);
647 TLB_COUNT_ATTACH(reason_page_protect_none); 662 TLB_COUNT_ATTACH(reason_page_protect_none);
648 TLB_COUNT_ATTACH(reason_protect); 663 TLB_COUNT_ATTACH(reason_protect);
649 TLB_COUNT_ATTACH(reason_enter_kernel); 664 TLB_COUNT_ATTACH(reason_enter_kernel);
650 TLB_COUNT_ATTACH(reason_enter_user); 665 TLB_COUNT_ATTACH(reason_enter_user);
651 TLB_COUNT_ATTACH(reason_kenter); 666 TLB_COUNT_ATTACH(reason_kenter);
652 TLB_COUNT_ATTACH(reason_enter_l2pt_delref); 667 TLB_COUNT_ATTACH(reason_enter_l2pt_delref);
653 TLB_COUNT_ATTACH(reason_enter_l3pt_delref); 668 TLB_COUNT_ATTACH(reason_enter_l3pt_delref);
654 TLB_COUNT_ATTACH(reason_kremove); 669 TLB_COUNT_ATTACH(reason_kremove);
655 TLB_COUNT_ATTACH(reason_clear_modify); 670 TLB_COUNT_ATTACH(reason_clear_modify);
656 TLB_COUNT_ATTACH(reason_clear_reference); 671 TLB_COUNT_ATTACH(reason_clear_reference);
657 672
658 TLB_COUNT_ATTACH(asn_reuse); 673 TLB_COUNT_ATTACH(asn_reuse);
659 TLB_COUNT_ATTACH(asn_newgen); 674 TLB_COUNT_ATTACH(asn_newgen);
660 TLB_COUNT_ATTACH(asn_assign); 675 TLB_COUNT_ATTACH(asn_assign);
661 676
662 TLB_COUNT_ATTACH(activate_both_change); 677 TLB_COUNT_ATTACH(activate_both_change);
663 TLB_COUNT_ATTACH(activate_asn_change); 678 TLB_COUNT_ATTACH(activate_asn_change);
664 TLB_COUNT_ATTACH(activate_ptbr_change); 679 TLB_COUNT_ATTACH(activate_ptbr_change);
665 TLB_COUNT_ATTACH(activate_swpctx); 680 TLB_COUNT_ATTACH(activate_swpctx);
666 TLB_COUNT_ATTACH(activate_skip_swpctx); 681 TLB_COUNT_ATTACH(activate_skip_swpctx);
667} 682}
668 683
669static inline void 684static inline void
670pmap_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)
671{ 686{
672 /* Initialize the minimum number of fields. */ 687 /* Initialize the minimum number of fields. */
673 tlbctx->t_addrdata[0] = 0; 688 tlbctx->t_addrdata[0] = 0;
674 tlbctx->t_addrdata[1] = flags; 689 tlbctx->t_addrdata[1] = flags;
675 tlbctx->t_pmap = NULL; 690 tlbctx->t_pmap = NULL;
676 LIST_INIT(&tlbctx->t_freeptq); 691 LIST_INIT(&tlbctx->t_freeptq);
677} 692}
678 693
679static void 694static void
680pmap_tlb_shootdown_internal(pmap_t const pmap, vaddr_t const va, 695pmap_tlb_shootdown_internal(pmap_t const pmap, vaddr_t const va,
681 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)
682{ 697{
683 KASSERT(pmap != NULL); 698 KASSERT(pmap != NULL);
684 KASSERT((va & PAGE_MASK) == 0); 699 KASSERT((va & PAGE_MASK) == 0);
685 700
686 /* 701 /*
687 * Figure out who needs to hear about this, and the scope 702 * Figure out who needs to hear about this, and the scope
688 * of an all-entries invalidate. 703 * of an all-entries invalidate.
689 */ 704 */
690 if (pmap == pmap_kernel()) { 705 if (pmap == pmap_kernel()) {
691 TLB_COUNT(shootdown_kernel); 706 TLB_COUNT(shootdown_kernel);
692 KASSERT(pte_bits & PG_ASM); 707 KASSERT(pte_bits & PG_ASM);
693 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_ASM); 708 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_ASM);
694 709
695 /* Note if an I-stream sync is also needed. */ 710 /* Note if an I-stream sync is also needed. */
696 if (pte_bits & PG_EXEC) { 711 if (pte_bits & PG_EXEC) {
697 TLB_COUNT(shootdown_kimb); 712 TLB_COUNT(shootdown_kimb);
698 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_KIMB); 713 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_KIMB);
699 } 714 }
700 } else { 715 } else {
701 TLB_COUNT(shootdown_user); 716 TLB_COUNT(shootdown_user);
702 KASSERT((pte_bits & PG_ASM) == 0); 717 KASSERT((pte_bits & PG_ASM) == 0);
703 718
704 /* Note if an I-stream sync is also needed. */ 719 /* Note if an I-stream sync is also needed. */
705 if (pte_bits & PG_EXEC) { 720 if (pte_bits & PG_EXEC) {
706 TLB_COUNT(shootdown_imb); 721 TLB_COUNT(shootdown_imb);
707 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_IMB); 722 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_IMB);
708 } 723 }
709 } 724 }
710 725
711 KASSERT(tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap); 726 KASSERT(tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap);
712 tlbctx->t_pmap = pmap; 727 tlbctx->t_pmap = pmap;
713 728
714 /* 729 /*
715 * 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
716 * to nail everything. 731 * to nail everything.
717 */ 732 */
718 const uintptr_t count = TLB_CTX_COUNT(tlbctx); 733 const uintptr_t count = TLB_CTX_COUNT(tlbctx);
719 if (count > TLB_CTX_MAXVA) { 734 if (count > TLB_CTX_MAXVA) {
720 return; 735 return;
721 } 736 }
722 if (count == TLB_CTX_MAXVA) { 737 if (count == TLB_CTX_MAXVA) {
723 TLB_COUNT(shootdown_overflow); 738 TLB_COUNT(shootdown_overflow);
724 TLB_CTX_SET_ALLVA(tlbctx); 739 TLB_CTX_SET_ALLVA(tlbctx);
725 return; 740 return;
726 } 741 }
727 742
728 TLB_CTX_SETVA(tlbctx, count, va); 743 TLB_CTX_SETVA(tlbctx, count, va);
729 TLB_CTX_INC_COUNT(tlbctx); 744 TLB_CTX_INC_COUNT(tlbctx);
730} 745}
731 746
732static void 747static void
733pmap_tlb_shootdown(pmap_t const pmap, vaddr_t const va, 748pmap_tlb_shootdown(pmap_t const pmap, vaddr_t const va,
734 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)
735{ 750{
736 KASSERT((TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV) == 0); 751 KASSERT((TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV) == 0);
737 pmap_tlb_shootdown_internal(pmap, va, pte_bits, tlbctx); 752 pmap_tlb_shootdown_internal(pmap, va, pte_bits, tlbctx);
738} 753}
739 754
740static void 755static void
741pmap_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,
742 struct pmap_tlb_context * const tlbctx) 757 struct pmap_tlb_context * const tlbctx)
743{ 758{
744 KASSERT(pmap != pmap_kernel()); 759 KASSERT(pmap != pmap_kernel());
745 760
746 TLB_COUNT(shootdown_all_user); 761 TLB_COUNT(shootdown_all_user);
747 762
748 /* Note if an I-stream sync is also needed. */ 763 /* Note if an I-stream sync is also needed. */
749 if (pte_bits & PG_EXEC) { 764 if (pte_bits & PG_EXEC) {
750 TLB_COUNT(shootdown_all_user_imb); 765 TLB_COUNT(shootdown_all_user_imb);
751 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_IMB); 766 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_IMB);
752 } 767 }
753 768
754 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV) { 769 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV) {
755 if (tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap) { 770 if (tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap) {
756 if (tlbctx->t_pmap == NULL) { 771 if (tlbctx->t_pmap == NULL) {
757 pmap_reference(pmap); 772 pmap_reference(pmap);
758 tlbctx->t_pmap = pmap; 773 tlbctx->t_pmap = pmap;
759 } 774 }
760 } else { 775 } else {
761 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_MULTI); 776 TLB_CTX_SET_FLAG(tlbctx, TLB_CTX_F_MULTI);
762 } 777 }
763 } else { 778 } else {
764 KASSERT(tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap); 779 KASSERT(tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap);
765 tlbctx->t_pmap = pmap; 780 tlbctx->t_pmap = pmap;
766 } 781 }
767 782
768 TLB_CTX_SET_ALLVA(tlbctx); 783 TLB_CTX_SET_ALLVA(tlbctx);
769} 784}
770 785
771static void 786static void
772pmap_tlb_shootdown_pv(pmap_t const pmap, vaddr_t const va, 787pmap_tlb_shootdown_pv(pmap_t const pmap, vaddr_t const va,
773 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)
774{ 789{
775 790
776 KASSERT(TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV); 791 KASSERT(TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV);
777 792
778 TLB_COUNT(shootdown_pv); 793 TLB_COUNT(shootdown_pv);
779 794
780 if (tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap) { 795 if (tlbctx->t_pmap == NULL || tlbctx->t_pmap == pmap) {
781 if (tlbctx->t_pmap == NULL) { 796 if (tlbctx->t_pmap == NULL) {
782 pmap_reference(pmap); 797 pmap_reference(pmap);
783 tlbctx->t_pmap = pmap; 798 tlbctx->t_pmap = pmap;
784 } 799 }
785 pmap_tlb_shootdown_internal(pmap, va, pte_bits, tlbctx); 800 pmap_tlb_shootdown_internal(pmap, va, pte_bits, tlbctx);
786 } else { 801 } else {
787 TLB_COUNT(shootdown_pv_multi); 802 TLB_COUNT(shootdown_pv_multi);
788 uintptr_t flags = TLB_CTX_F_MULTI; 803 uintptr_t flags = TLB_CTX_F_MULTI;
789 if (pmap == pmap_kernel()) { 804 if (pmap == pmap_kernel()) {
790 KASSERT(pte_bits & PG_ASM); 805 KASSERT(pte_bits & PG_ASM);
791 flags |= TLB_CTX_F_ASM; 806 flags |= TLB_CTX_F_ASM;
792 } else { 807 } else {
793 KASSERT((pte_bits & PG_ASM) == 0); 808 KASSERT((pte_bits & PG_ASM) == 0);
794 } 809 }
795 810
796 /* 811 /*
797 * No need to distinguish between kernel and user IMB 812 * No need to distinguish between kernel and user IMB
798 * here; see pmap_tlb_invalidate_multi(). 813 * here; see pmap_tlb_invalidate_multi().
799 */ 814 */
800 if (pte_bits & PG_EXEC) { 815 if (pte_bits & PG_EXEC) {
801 flags |= TLB_CTX_F_IMB; 816 flags |= TLB_CTX_F_IMB;
802 } 817 }
803 TLB_CTX_SET_ALLVA(tlbctx); 818 TLB_CTX_SET_ALLVA(tlbctx);
804 TLB_CTX_SET_FLAG(tlbctx, flags); 819 TLB_CTX_SET_FLAG(tlbctx, flags);
805 } 820 }
806} 821}
807 822
808static void 823static void
809pmap_tlb_invalidate_multi(const struct pmap_tlb_context * const tlbctx) 824pmap_tlb_invalidate_multi(const struct pmap_tlb_context * const tlbctx)
810{ 825{
811 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_ASM) { 826 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_ASM) {
812 TLB_COUNT(invalidate_multi_tbia); 827 TLB_COUNT(invalidate_multi_tbia);
813 ALPHA_TBIA(); 828 ALPHA_TBIA();
814 } else { 829 } else {
815 TLB_COUNT(invalidate_multi_tbiap); 830 TLB_COUNT(invalidate_multi_tbiap);
816 ALPHA_TBIAP(); 831 ALPHA_TBIAP();
817 } 832 }
818 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)) {
819 TLB_COUNT(invalidate_multi_imb); 834 TLB_COUNT(invalidate_multi_imb);
820 alpha_pal_imb(); 835 alpha_pal_imb();
821 } 836 }
822} 837}
823 838
824static void 839static void
825pmap_tlb_invalidate_kernel(const struct pmap_tlb_context * const tlbctx) 840pmap_tlb_invalidate_kernel(const struct pmap_tlb_context * const tlbctx)
826{ 841{
827 const uintptr_t count = TLB_CTX_COUNT(tlbctx); 842 const uintptr_t count = TLB_CTX_COUNT(tlbctx);
828 843
829 if (count == TLB_CTX_ALLVA) { 844 if (count == TLB_CTX_ALLVA) {
830 TLB_COUNT(invalidate_kern_tbia); 845 TLB_COUNT(invalidate_kern_tbia);
831 ALPHA_TBIA(); 846 ALPHA_TBIA();
832 } else { 847 } else {
833 TLB_COUNT(invalidate_kern_tbis); 848 TLB_COUNT(invalidate_kern_tbis);
834 for (uintptr_t i = 0; i < count; i++) { 849 for (uintptr_t i = 0; i < count; i++) {
835 ALPHA_TBIS(TLB_CTX_VA(tlbctx, i)); 850 ALPHA_TBIS(TLB_CTX_VA(tlbctx, i));
836 } 851 }
837 } 852 }
838 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_KIMB) { 853 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_KIMB) {
839 TLB_COUNT(invalidate_kern_imb); 854 TLB_COUNT(invalidate_kern_imb);
840 alpha_pal_imb(); 855 alpha_pal_imb();
841 } 856 }
842} 857}
843 858
844static void 859static void
845pmap_tlb_invalidate(const struct pmap_tlb_context * const tlbctx, 860pmap_tlb_invalidate(const struct pmap_tlb_context * const tlbctx,
846 const struct cpu_info * const ci) 861 const struct cpu_info * const ci)
847{ 862{
848 const uintptr_t count = TLB_CTX_COUNT(tlbctx); 863 const uintptr_t count = TLB_CTX_COUNT(tlbctx);
849 864
850 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_MULTI) { 865 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_MULTI) {
851 pmap_tlb_invalidate_multi(tlbctx); 866 pmap_tlb_invalidate_multi(tlbctx);
852 return; 867 return;
853 } 868 }
854 869
855 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_ASM) { 870 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_ASM) {
856 pmap_tlb_invalidate_kernel(tlbctx); 871 pmap_tlb_invalidate_kernel(tlbctx);
857 return; 872 return;
858 } 873 }
859 874
860 KASSERT(kpreempt_disabled()); 875 KASSERT(kpreempt_disabled());
861 876
862 pmap_t const pmap = tlbctx->t_pmap; 877 pmap_t const pmap = tlbctx->t_pmap;
863 KASSERT(pmap != NULL); 878 KASSERT(pmap != NULL);
864 879
865 if (__predict_false(pmap != ci->ci_pmap)) { 880 if (__predict_false(pmap != ci->ci_pmap)) {
866 TLB_COUNT(invalidate_user_not_current); 881 TLB_COUNT(invalidate_user_not_current);
867 882
868 /* 883 /*
869 * For CPUs that don't implement ASNs, the SWPCTX call 884 * For CPUs that don't implement ASNs, the SWPCTX call
870 * does all of the TLB invalidation work for us. 885 * does all of the TLB invalidation work for us.
871 */ 886 */
872 if (__predict_false(pmap_max_asn == 0)) { 887 if (__predict_false(pmap_max_asn == 0)) {
873 return; 888 return;
874 } 889 }
875 890
876 const u_long cpu_mask = 1UL << ci->ci_cpuid; 891 const u_long cpu_mask = 1UL << ci->ci_cpuid;
877 892
878 /* 893 /*
879 * We cannot directly invalidate the TLB in this case, 894 * We cannot directly invalidate the TLB in this case,
880 * so force allocation of a new ASN when the pmap becomes 895 * so force allocation of a new ASN when the pmap becomes
881 * active again. 896 * active again.
882 */ 897 */
883 pmap->pm_percpu[ci->ci_cpuid].pmc_asngen = PMAP_ASNGEN_INVALID; 898 pmap->pm_percpu[ci->ci_cpuid].pmc_asngen = PMAP_ASNGEN_INVALID;
884 atomic_and_ulong(&pmap->pm_cpus, ~cpu_mask); 899 atomic_and_ulong(&pmap->pm_cpus, ~cpu_mask);
885 900
886 /* 901 /*
887 * This isn't strictly necessary; when we allocate a 902 * This isn't strictly necessary; when we allocate a
888 * new ASN, we're going to clear this bit and skip 903 * new ASN, we're going to clear this bit and skip
889 * syncing the I-stream. But we will keep this bit 904 * syncing the I-stream. But we will keep this bit
890 * of accounting for internal consistency. 905 * of accounting for internal consistency.
891 */ 906 */
892 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_IMB) { 907 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_IMB) {
893 pmap->pm_percpu[ci->ci_cpuid].pmc_needisync = 1; 908 pmap->pm_percpu[ci->ci_cpuid].pmc_needisync = 1;
894 } 909 }
895 return; 910 return;
896 } 911 }
897 912
898 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_IMB) { 913 if (TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_IMB) {
899 TLB_COUNT(invalidate_user_lazy_imb); 914 TLB_COUNT(invalidate_user_lazy_imb);
900 pmap->pm_percpu[ci->ci_cpuid].pmc_needisync = 1; 915 pmap->pm_percpu[ci->ci_cpuid].pmc_needisync = 1;
901 } 916 }
902 917
903 if (count == TLB_CTX_ALLVA) { 918 if (count == TLB_CTX_ALLVA) {
904 /* 919 /*
905 * Another option here for CPUs that implement ASNs is 920 * Another option here for CPUs that implement ASNs is
906 * 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
907 * certainly faster than a TBIAP, but would require us 922 * certainly faster than a TBIAP, but would require us
908 * to synchronize against IPIs in pmap_activate(). 923 * to synchronize against IPIs in pmap_activate().
909 */ 924 */
910 TLB_COUNT(invalidate_user_tbiap); 925 TLB_COUNT(invalidate_user_tbiap);
911 KASSERT((TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_ASM) == 0); 926 KASSERT((TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_ASM) == 0);
912 ALPHA_TBIAP(); 927 ALPHA_TBIAP();
913 } else { 928 } else {
914 TLB_COUNT(invalidate_user_tbis); 929 TLB_COUNT(invalidate_user_tbis);
915 for (uintptr_t i = 0; i < count; i++) { 930 for (uintptr_t i = 0; i < count; i++) {
916 ALPHA_TBIS(TLB_CTX_VA(tlbctx, i)); 931 ALPHA_TBIS(TLB_CTX_VA(tlbctx, i));
917 } 932 }
918 } 933 }
919} 934}
920 935
921static void 936static void
922pmap_tlb_shootnow(const struct pmap_tlb_context * const tlbctx) 937pmap_tlb_shootnow(const struct pmap_tlb_context * const tlbctx)
923{ 938{
924 939
925 if (TLB_CTX_COUNT(tlbctx) == 0) { 940 if (TLB_CTX_COUNT(tlbctx) == 0) {
926 /* No work to do. */ 941 /* No work to do. */
927 return; 942 return;
928 } 943 }
929 944
930 /* 945 /*
931 * Acquire the shootdown mutex. This will also block IPL_VM 946 * Acquire the shootdown mutex. This will also block IPL_VM
932 * interrupts and disable preemption. It is critically important 947 * interrupts and disable preemption. It is critically important
933 * that IPIs not be blocked in this routine. 948 * that IPIs not be blocked in this routine.
934 */ 949 */
935 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);
936 mutex_spin_enter(&tlb_lock); 951 mutex_spin_enter(&tlb_lock);
937 tlb_evcnt.ev_count++; 952 tlb_evcnt.ev_count++;
938 953
939 const struct cpu_info *ci = curcpu(); 954 const struct cpu_info *ci = curcpu();
940 const u_long this_cpu = 1UL << ci->ci_cpuid; 955 const u_long this_cpu = 1UL << ci->ci_cpuid;
941 u_long active_cpus; 956 u_long active_cpus;
942 bool activation_locked, activation_lock_tried; 957 bool activation_locked, activation_lock_tried;
943 958
944 /* 959 /*
945 * 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
946 * multiple aaddress spaces, we notify everybody. If 961 * multiple aaddress spaces, we notify everybody. If
947 * 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
948 * activation lock so we can get an accurate accounting 963 * activation lock so we can get an accurate accounting
949 * of who needs to be notified. If we can't acquire 964 * of who needs to be notified. If we can't acquire
950 * the activation lock, then just notify everyone and 965 * the activation lock, then just notify everyone and
951 * let them sort it out when they process the IPI. 966 * let them sort it out when they process the IPI.
952 */ 967 */
953 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)) {
954 active_cpus = pmap_all_cpus(); 969 active_cpus = pmap_all_cpus();
955 activation_locked = false; 970 activation_locked = false;
956 activation_lock_tried = false; 971 activation_lock_tried = false;
957 } else { 972 } else {
958 KASSERT(tlbctx->t_pmap != NULL); 973 KASSERT(tlbctx->t_pmap != NULL);
959 activation_locked = PMAP_ACT_TRYLOCK(tlbctx->t_pmap); 974 activation_locked = PMAP_ACT_TRYLOCK(tlbctx->t_pmap);
960 if (__predict_true(activation_locked)) { 975 if (__predict_true(activation_locked)) {
961 active_cpus = tlbctx->t_pmap->pm_cpus; 976 active_cpus = tlbctx->t_pmap->pm_cpus;
962 } else { 977 } else {
963 TLB_COUNT(shootnow_over_notify); 978 TLB_COUNT(shootnow_over_notify);
964 active_cpus = pmap_all_cpus(); 979 active_cpus = pmap_all_cpus();
965 } 980 }
966 activation_lock_tried = true; 981 activation_lock_tried = true;
967 } 982 }
968 983
969#if defined(MULTIPROCESSOR) 984#if defined(MULTIPROCESSOR)
970 /* 985 /*
971 * 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
972 * started now. 987 * started now.
973 */ 988 */
974 const u_long remote_cpus = active_cpus & ~this_cpu; 989 const u_long remote_cpus = active_cpus & ~this_cpu;
975 KASSERT(tlb_context == NULL); 990 KASSERT(tlb_context == NULL);
976 if (remote_cpus) { 991 if (remote_cpus) {
977 TLB_COUNT(shootnow_remote); 992 TLB_COUNT(shootnow_remote);
978 tlb_context = tlbctx; 993 tlb_context = tlbctx;
979 tlb_pending = remote_cpus; 994 tlb_pending = remote_cpus;
980 alpha_multicast_ipi(remote_cpus, ALPHA_IPI_SHOOTDOWN); 995 alpha_multicast_ipi(remote_cpus, ALPHA_IPI_SHOOTDOWN);
981 } 996 }
982#endif /* MULTIPROCESSOR */ 997#endif /* MULTIPROCESSOR */
983 998
984 /* 999 /*
985 * Now that the remotes have been notified, release the 1000 * Now that the remotes have been notified, release the
986 * activation lock. 1001 * activation lock.
987 */ 1002 */
988 if (activation_lock_tried) { 1003 if (activation_lock_tried) {
989 if (activation_locked) { 1004 if (activation_locked) {
990 KASSERT(tlbctx->t_pmap != NULL); 1005 KASSERT(tlbctx->t_pmap != NULL);
991 PMAP_ACT_UNLOCK(tlbctx->t_pmap); 1006 PMAP_ACT_UNLOCK(tlbctx->t_pmap);
992 } 1007 }
993 /* 1008 /*
994 * When we tried to acquire the activation lock, we 1009 * When we tried to acquire the activation lock, we
995 * raised IPL to IPL_SCHED (even if we ultimately 1010 * raised IPL to IPL_SCHED (even if we ultimately
996 * failed to acquire the lock), which blocks out IPIs. 1011 * failed to acquire the lock), which blocks out IPIs.
997 * 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
998 * receive IPIs. 1013 * receive IPIs.
999 */ 1014 */
1000 alpha_pal_swpipl(IPL_VM); 1015 alpha_pal_swpipl(IPL_VM);
1001 } 1016 }
1002 1017
1003 /* 1018 /*
1004 * 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
1005 * synchronize with activation here because we know that 1020 * synchronize with activation here because we know that
1006 * for the current CPU, activation status will not change. 1021 * for the current CPU, activation status will not change.
1007 */ 1022 */
1008 if (active_cpus & this_cpu) { 1023 if (active_cpus & this_cpu) {
1009 pmap_tlb_invalidate(tlbctx, ci); 1024 pmap_tlb_invalidate(tlbctx, ci);
1010 } 1025 }
1011 1026
1012#if defined(MULTIPROCESSOR) 1027#if defined(MULTIPROCESSOR)
1013 /* Wait for remote CPUs to finish. */ 1028 /* Wait for remote CPUs to finish. */
1014 if (remote_cpus) { 1029 if (remote_cpus) {
1015 int backoff = SPINLOCK_BACKOFF_MIN; 1030 int backoff = SPINLOCK_BACKOFF_MIN;
1016 u_int spins = 0; 1031 u_int spins = 0;
1017 1032
1018 while (atomic_load_acquire(&tlb_context) != NULL) { 1033 while (atomic_load_acquire(&tlb_context) != NULL) {
1019 SPINLOCK_BACKOFF(backoff); 1034 SPINLOCK_BACKOFF(backoff);
1020 if (spins++ > 0x0fffffff) { 1035 if (spins++ > 0x0fffffff) {
1021 printf("TLB LOCAL MASK = 0x%016lx\n", 1036 printf("TLB LOCAL MASK = 0x%016lx\n",
1022 this_cpu); 1037 this_cpu);
1023 printf("TLB REMOTE MASK = 0x%016lx\n", 1038 printf("TLB REMOTE MASK = 0x%016lx\n",
1024 remote_cpus); 1039 remote_cpus);
1025 printf("TLB REMOTE PENDING = 0x%016lx\n", 1040 printf("TLB REMOTE PENDING = 0x%016lx\n",
1026 tlb_pending); 1041 tlb_pending);
1027 printf("TLB CONTEXT = %p\n", tlb_context); 1042 printf("TLB CONTEXT = %p\n", tlb_context);
1028 printf("TLB LOCAL IPL = %lu\n", 1043 printf("TLB LOCAL IPL = %lu\n",
1029 alpha_pal_rdps() & ALPHA_PSL_IPL_MASK); 1044 alpha_pal_rdps() & ALPHA_PSL_IPL_MASK);
1030 panic("pmap_tlb_shootnow"); 1045 panic("pmap_tlb_shootnow");
1031 } 1046 }
1032 } 1047 }
1033 } 1048 }
1034 KASSERT(tlb_context == NULL); 1049 KASSERT(tlb_context == NULL);
1035#endif /* MULTIPROCESSOR */ 1050#endif /* MULTIPROCESSOR */
1036 1051
1037 mutex_spin_exit(&tlb_lock); 1052 mutex_spin_exit(&tlb_lock);
1038 1053
1039 if (__predict_false(TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV)) { 1054 if (__predict_false(TLB_CTX_FLAGS(tlbctx) & TLB_CTX_F_PV)) {
1040 /* 1055 /*
1041 * P->V TLB operations may operate on multiple pmaps. 1056 * P->V TLB operations may operate on multiple pmaps.
1042 * The shootdown takes a reference on the first pmap it 1057 * The shootdown takes a reference on the first pmap it
1043 * encounters, in order to prevent it from disappearing, 1058 * encounters, in order to prevent it from disappearing,
1044 * 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
1045 * operation (instrumentation shows this is not rare). 1060 * operation (instrumentation shows this is not rare).
1046 * 1061 *
1047 * Once this shootdown is finished globally, we need to 1062 * Once this shootdown is finished globally, we need to
1048 * release this extra reference. 1063 * release this extra reference.
1049 */ 1064 */
1050 KASSERT(tlbctx->t_pmap != NULL); 1065 KASSERT(tlbctx->t_pmap != NULL);
1051 pmap_destroy(tlbctx->t_pmap); 1066 pmap_destroy(tlbctx->t_pmap);
1052 } 1067 }
1053} 1068}
1054 1069
1055#if defined(MULTIPROCESSOR) 1070#if defined(MULTIPROCESSOR)
1056void 1071void
1057pmap_tlb_shootdown_ipi(struct cpu_info * const ci, 1072pmap_tlb_shootdown_ipi(struct cpu_info * const ci,
1058 1073
1059 struct trapframe * const tf __unused) 1074 struct trapframe * const tf __unused)
1060{ 1075{
1061 KASSERT(tlb_context != NULL); 1076 KASSERT(tlb_context != NULL);
1062 pmap_tlb_invalidate(tlb_context, ci); 1077 pmap_tlb_invalidate(tlb_context, ci);
1063 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) {
1064 atomic_store_release(&tlb_context, NULL); 1079 atomic_store_release(&tlb_context, NULL);
1065 } 1080 }
1066} 1081}
1067#endif /* MULTIPROCESSOR */ 1082#endif /* MULTIPROCESSOR */
1068 1083
1069static void 1084static void
1070pmap_tlb_physpage_free(paddr_t const ptpa, 1085pmap_tlb_physpage_free(paddr_t const ptpa,
1071 struct pmap_tlb_context * const tlbctx) 1086 struct pmap_tlb_context * const tlbctx)
1072{ 1087{
1073 struct vm_page * const pg = PHYS_TO_VM_PAGE(ptpa); 1088 struct vm_page * const pg = PHYS_TO_VM_PAGE(ptpa);
1074 1089
1075 KASSERT(pg != NULL); 1090 KASSERT(pg != NULL);
1076 1091
1077#ifdef DEBUG 1092#ifdef DEBUG
1078 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 1093 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
1079 KDASSERT(md->pvh_refcnt == 0); 1094 KDASSERT(md->pvh_refcnt == 0);
1080#endif 1095#endif
1081 1096
1082 LIST_INSERT_HEAD(&tlbctx->t_freeptq, pg, pageq.list); 1097 LIST_INSERT_HEAD(&tlbctx->t_freeptq, pg, pageq.list);
1083} 1098}
1084 1099
1085static void 1100static __inline void
1086pmap_tlb_ptpage_drain(struct pmap_tlb_context * const tlbctx) 1101pmap_tlb_ptpage_drain(struct pmap_tlb_context * const tlbctx)
1087{ 1102{
1088 struct vm_page *pg; 1103 pmap_pagelist_free(&tlbctx->t_freeptq);
1089 
1090 while ((pg = LIST_FIRST(&tlbctx->t_freeptq)) != NULL) { 
1091 LIST_REMOVE(pg, pageq.list); 
1092 uvm_pagefree(pg); 
1093 } 
1094} 1104}
1095 1105
1096/* 1106/*
1097 * Internal routines 1107 * Internal routines
1098 */ 1108 */
1099static void alpha_protection_init(void); 1109static void alpha_protection_init(void);
1100static pt_entry_t pmap_remove_mapping(pmap_t, vaddr_t, pt_entry_t *, bool, 1110static pt_entry_t pmap_remove_mapping(pmap_t, vaddr_t, pt_entry_t *, bool,
1101 pv_entry_t *, 1111 pv_entry_t *,
1102 struct pmap_tlb_context *); 1112 struct pmap_tlb_context *);
1103static void pmap_changebit(struct vm_page *, pt_entry_t, pt_entry_t, 1113static void pmap_changebit(struct vm_page *, pt_entry_t, pt_entry_t,
1104 struct pmap_tlb_context *); 1114 struct pmap_tlb_context *);
1105 1115
1106/* 1116/*
1107 * PT page management functions. 1117 * PT page management functions.
1108 */ 1118 */
1109static int pmap_ptpage_alloc(pt_entry_t *, int); 1119static int pmap_ptpage_alloc(pt_entry_t *, int);
1110static void pmap_ptpage_free(pt_entry_t *, struct pmap_tlb_context *); 1120static void pmap_ptpage_free(pt_entry_t *, struct pmap_tlb_context *);
1111static void pmap_l3pt_delref(pmap_t, vaddr_t, pt_entry_t *, 1121static void pmap_l3pt_delref(pmap_t, vaddr_t, pt_entry_t *,
1112 struct pmap_tlb_context *); 1122 struct pmap_tlb_context *);
1113static void pmap_l2pt_delref(pmap_t, pt_entry_t *, pt_entry_t *, 1123static void pmap_l2pt_delref(pmap_t, pt_entry_t *, pt_entry_t *,
1114 struct pmap_tlb_context *); 1124 struct pmap_tlb_context *);
1115static void pmap_l1pt_delref(pmap_t, pt_entry_t *); 1125static void pmap_l1pt_delref(pmap_t, pt_entry_t *);
1116 1126
1117static void *pmap_l1pt_alloc(struct pool *, int); 1127static void *pmap_l1pt_alloc(struct pool *, int);
1118static void pmap_l1pt_free(struct pool *, void *); 1128static void pmap_l1pt_free(struct pool *, void *);
1119 1129
1120static struct pool_allocator pmap_l1pt_allocator = { 1130static struct pool_allocator pmap_l1pt_allocator = {
1121 pmap_l1pt_alloc, pmap_l1pt_free, 0, 1131 pmap_l1pt_alloc, pmap_l1pt_free, 0,
1122}; 1132};
1123 1133
1124static int pmap_l1pt_ctor(void *, void *, int); 1134static int pmap_l1pt_ctor(void *, void *, int);
1125 1135
1126/* 1136/*
1127 * PV table management functions. 1137 * PV table management functions.
1128 */ 1138 */
1129static int pmap_pv_enter(pmap_t, struct vm_page *, vaddr_t, pt_entry_t *, 1139static int pmap_pv_enter(pmap_t, struct vm_page *, vaddr_t, pt_entry_t *,
1130 bool, pv_entry_t); 1140 bool, pv_entry_t);
1131static void pmap_pv_remove(pmap_t, struct vm_page *, vaddr_t, bool, 1141static void pmap_pv_remove(pmap_t, struct vm_page *, vaddr_t, bool,
1132 pv_entry_t *); 1142 pv_entry_t *);
1133static void *pmap_pv_page_alloc(struct pool *, int); 1143static void *pmap_pv_page_alloc(struct pool *, int);
1134static void pmap_pv_page_free(struct pool *, void *); 1144static void pmap_pv_page_free(struct pool *, void *);
1135 1145
1136static struct pool_allocator pmap_pv_page_allocator = { 1146static struct pool_allocator pmap_pv_page_allocator = {
1137 pmap_pv_page_alloc, pmap_pv_page_free, 0, 1147 pmap_pv_page_alloc, pmap_pv_page_free, 0,
1138}; 1148};
1139 1149
1140#ifdef DEBUG 1150#ifdef DEBUG
1141void pmap_pv_dump(paddr_t); 1151void pmap_pv_dump(paddr_t);
1142#endif 1152#endif
1143 1153
1144#define pmap_pv_alloc() pool_cache_get(&pmap_pv_cache, PR_NOWAIT) 1154#define pmap_pv_alloc() pool_cache_get(&pmap_pv_cache, PR_NOWAIT)
1145#define pmap_pv_free(pv) pool_cache_put(&pmap_pv_cache, (pv)) 1155#define pmap_pv_free(pv) pool_cache_put(&pmap_pv_cache, (pv))
1146 1156
1147/* 1157/*
1148 * ASN management functions. 1158 * ASN management functions.
1149 */ 1159 */
1150static u_int pmap_asn_alloc(pmap_t, struct cpu_info *); 1160static u_int pmap_asn_alloc(pmap_t, struct cpu_info *);
1151 1161
1152/* 1162/*
1153 * Misc. functions. 1163 * Misc. functions.
1154 */ 1164 */
1155static bool pmap_physpage_alloc(int, paddr_t *); 1165static bool pmap_physpage_alloc(int, paddr_t *);
1156static void pmap_physpage_free(paddr_t); 1166static void pmap_physpage_free(paddr_t);
1157static int pmap_physpage_addref(void *); 1167static int pmap_physpage_addref(void *);
1158static int pmap_physpage_delref(void *); 1168static int pmap_physpage_delref(void *);
1159 1169
1160static bool vtophys_internal(vaddr_t, paddr_t *p); 1170static bool vtophys_internal(vaddr_t, paddr_t *p);
1161 1171
1162/* 1172/*
1163 * PMAP_KERNEL_PTE: 1173 * PMAP_KERNEL_PTE:
1164 * 1174 *
1165 * Get a kernel PTE. 1175 * Get a kernel PTE.
1166 * 1176 *
1167 * If debugging, do a table walk. If not debugging, just use 1177 * If debugging, do a table walk. If not debugging, just use
1168 * the Virtual Page Table, since all kernel page tables are 1178 * the Virtual Page Table, since all kernel page tables are
1169 * pre-allocated and mapped in. 1179 * pre-allocated and mapped in.
1170 */ 1180 */
1171#ifdef DEBUG 1181#ifdef DEBUG
1172#define PMAP_KERNEL_PTE(va) \ 1182#define PMAP_KERNEL_PTE(va) \
1173({ \ 1183({ \
1174 pt_entry_t *l1pte_, *l2pte_; \ 1184 pt_entry_t *l1pte_, *l2pte_; \
1175 \ 1185 \
1176 l1pte_ = pmap_l1pte(kernel_lev1map, va); \ 1186 l1pte_ = pmap_l1pte(kernel_lev1map, va); \
1177 if (pmap_pte_v(l1pte_) == 0) { \ 1187 if (pmap_pte_v(l1pte_) == 0) { \
1178 printf("kernel level 1 PTE not valid, va 0x%lx " \ 1188 printf("kernel level 1 PTE not valid, va 0x%lx " \
1179 "(line %d)\n", (va), __LINE__); \ 1189 "(line %d)\n", (va), __LINE__); \
1180 panic("PMAP_KERNEL_PTE"); \ 1190 panic("PMAP_KERNEL_PTE"); \
1181 } \ 1191 } \
1182 l2pte_ = pmap_l2pte(kernel_lev1map, va, l1pte_); \ 1192 l2pte_ = pmap_l2pte(kernel_lev1map, va, l1pte_); \
1183 if (pmap_pte_v(l2pte_) == 0) { \ 1193 if (pmap_pte_v(l2pte_) == 0) { \
1184 printf("kernel level 2 PTE not valid, va 0x%lx " \ 1194 printf("kernel level 2 PTE not valid, va 0x%lx " \
1185 "(line %d)\n", (va), __LINE__); \ 1195 "(line %d)\n", (va), __LINE__); \
1186 panic("PMAP_KERNEL_PTE"); \ 1196 panic("PMAP_KERNEL_PTE"); \
1187 } \ 1197 } \
1188 pmap_l3pte(kernel_lev1map, va, l2pte_); \ 1198 pmap_l3pte(kernel_lev1map, va, l2pte_); \
1189}) 1199})
1190#else 1200#else
1191#define PMAP_KERNEL_PTE(va) (&VPT[VPT_INDEX((va))]) 1201#define PMAP_KERNEL_PTE(va) (&VPT[VPT_INDEX((va))])
1192#endif 1202#endif
1193 1203
1194/* 1204/*
1195 * PMAP_STAT_{INCR,DECR}: 1205 * PMAP_STAT_{INCR,DECR}:
1196 * 1206 *
1197 * Increment or decrement a pmap statistic. 1207 * Increment or decrement a pmap statistic.
1198 */ 1208 */
1199#define PMAP_STAT_INCR(s, v) atomic_add_long((unsigned long *)(&(s)), (v)) 1209#define PMAP_STAT_INCR(s, v) atomic_add_long((unsigned long *)(&(s)), (v))
1200#define PMAP_STAT_DECR(s, v) atomic_add_long((unsigned long *)(&(s)), -(v)) 1210#define PMAP_STAT_DECR(s, v) atomic_add_long((unsigned long *)(&(s)), -(v))
1201 1211
1202/* 1212/*
1203 * pmap_init_cpu: 1213 * pmap_init_cpu:
1204 * 1214 *
1205 * Initilize pmap data in the cpu_info. 1215 * Initilize pmap data in the cpu_info.
1206 */ 1216 */
1207void 1217void
1208pmap_init_cpu(struct cpu_info * const ci) 1218pmap_init_cpu(struct cpu_info * const ci)
1209{ 1219{
1210 pmap_t const pmap = pmap_kernel(); 1220 pmap_t const pmap = pmap_kernel();
1211 1221
1212 /* All CPUs start out using the kernel pmap. */ 1222 /* All CPUs start out using the kernel pmap. */
1213 atomic_or_ulong(&pmap->pm_cpus, 1UL << ci->ci_cpuid); 1223 atomic_or_ulong(&pmap->pm_cpus, 1UL << ci->ci_cpuid);
1214 pmap_reference(pmap); 1224 pmap_reference(pmap);
1215 ci->ci_pmap = pmap; 1225 ci->ci_pmap = pmap;
1216 1226
1217 /* Initialize ASN allocation logic. */ 1227 /* Initialize ASN allocation logic. */
1218 ci->ci_next_asn = PMAP_ASN_FIRST_USER; 1228 ci->ci_next_asn = PMAP_ASN_FIRST_USER;
1219 ci->ci_asn_gen = PMAP_ASNGEN_INITIAL; 1229 ci->ci_asn_gen = PMAP_ASNGEN_INITIAL;
1220} 1230}
1221 1231
1222/* 1232/*
1223 * pmap_bootstrap: 1233 * pmap_bootstrap:
1224 * 1234 *
1225 * Bootstrap the system to run with virtual memory. 1235 * Bootstrap the system to run with virtual memory.
1226 * 1236 *
1227 * Note: no locking is necessary in this function. 1237 * Note: no locking is necessary in this function.
1228 */ 1238 */
1229void 1239void
1230pmap_bootstrap(paddr_t ptaddr, u_int maxasn, u_long ncpuids) 1240pmap_bootstrap(paddr_t ptaddr, u_int maxasn, u_long ncpuids)
1231{ 1241{
1232 vsize_t lev2mapsize, lev3mapsize; 1242 vsize_t lev2mapsize, lev3mapsize;
1233 pt_entry_t *lev2map, *lev3map; 1243 pt_entry_t *lev2map, *lev3map;
1234 pt_entry_t pte; 1244 pt_entry_t pte;
1235 vsize_t bufsz; 1245 vsize_t bufsz;
1236 struct pcb *pcb; 1246 struct pcb *pcb;
1237 int i; 1247 int i;
1238 1248
1239#ifdef DEBUG 1249#ifdef DEBUG
1240 if (pmapdebug & (PDB_FOLLOW|PDB_BOOTSTRAP)) 1250 if (pmapdebug & (PDB_FOLLOW|PDB_BOOTSTRAP))
1241 printf("pmap_bootstrap(0x%lx, %u)\n", ptaddr, maxasn); 1251 printf("pmap_bootstrap(0x%lx, %u)\n", ptaddr, maxasn);
1242#endif 1252#endif
1243 1253
1244 /* 1254 /*
1245 * Compute the number of pages kmem_arena will have. 1255 * Compute the number of pages kmem_arena will have.
1246 */ 1256 */
1247 kmeminit_nkmempages(); 1257 kmeminit_nkmempages();
1248 1258
1249 /* 1259 /*
1250 * Figure out how many initial PTE's are necessary to map the 1260 * Figure out how many initial PTE's are necessary to map the
1251 * kernel. We also reserve space for kmem_alloc_pageable() 1261 * kernel. We also reserve space for kmem_alloc_pageable()
1252 * for vm_fork(). 1262 * for vm_fork().
1253 */ 1263 */
1254 1264
1255 /* Get size of buffer cache and set an upper limit */ 1265 /* Get size of buffer cache and set an upper limit */
1256 bufsz = buf_memcalc(); 1266 bufsz = buf_memcalc();
1257 buf_setvalimit(bufsz); 1267 buf_setvalimit(bufsz);
1258 1268
1259 lev3mapsize = 1269 lev3mapsize =
1260 (VM_PHYS_SIZE + (ubc_nwins << ubc_winshift) + 1270 (VM_PHYS_SIZE + (ubc_nwins << ubc_winshift) +
1261 bufsz + 16 * NCARGS + pager_map_size) / PAGE_SIZE + 1271 bufsz + 16 * NCARGS + pager_map_size) / PAGE_SIZE +
1262 (maxproc * UPAGES) + nkmempages; 1272 (maxproc * UPAGES) + nkmempages;
1263 1273
1264 lev3mapsize = roundup(lev3mapsize, NPTEPG); 1274 lev3mapsize = roundup(lev3mapsize, NPTEPG);
1265 1275
1266 /* 1276 /*
1267 * Initialize `FYI' variables. Note we're relying on 1277 * Initialize `FYI' variables. Note we're relying on
1268 * the fact that BSEARCH sorts the vm_physmem[] array 1278 * the fact that BSEARCH sorts the vm_physmem[] array
1269 * for us. 1279 * for us.
1270 */ 1280 */
1271 avail_start = ptoa(uvm_physseg_get_avail_start(uvm_physseg_get_first())); 1281 avail_start = ptoa(uvm_physseg_get_avail_start(uvm_physseg_get_first()));
1272 avail_end = ptoa(uvm_physseg_get_avail_end(uvm_physseg_get_last())); 1282 avail_end = ptoa(uvm_physseg_get_avail_end(uvm_physseg_get_last()));
1273 virtual_end = VM_MIN_KERNEL_ADDRESS + lev3mapsize * PAGE_SIZE; 1283 virtual_end = VM_MIN_KERNEL_ADDRESS + lev3mapsize * PAGE_SIZE;
1274 1284
1275#if 0 1285#if 0
1276 printf("avail_start = 0x%lx\n", avail_start); 1286 printf("avail_start = 0x%lx\n", avail_start);
1277 printf("avail_end = 0x%lx\n", avail_end); 1287 printf("avail_end = 0x%lx\n", avail_end);
1278 printf("virtual_end = 0x%lx\n", virtual_end); 1288 printf("virtual_end = 0x%lx\n", virtual_end);
1279#endif 1289#endif
1280 1290
1281 /* 1291 /*
1282 * Allocate a level 1 PTE table for the kernel. 1292 * Allocate a level 1 PTE table for the kernel.
1283 * This is always one page long. 1293 * This is always one page long.
1284 * IF THIS IS NOT A MULTIPLE OF PAGE_SIZE, ALL WILL GO TO HELL. 1294 * IF THIS IS NOT A MULTIPLE OF PAGE_SIZE, ALL WILL GO TO HELL.
1285 */ 1295 */
1286 kernel_lev1map = (pt_entry_t *) 1296 kernel_lev1map = (pt_entry_t *)
1287 uvm_pageboot_alloc(sizeof(pt_entry_t) * NPTEPG); 1297 uvm_pageboot_alloc(sizeof(pt_entry_t) * NPTEPG);
1288 1298
1289 /* 1299 /*
1290 * Allocate a level 2 PTE table for the kernel. 1300 * Allocate a level 2 PTE table for the kernel.
1291 * These must map all of the level3 PTEs. 1301 * These must map all of the level3 PTEs.
1292 * IF THIS IS NOT A MULTIPLE OF PAGE_SIZE, ALL WILL GO TO HELL. 1302 * IF THIS IS NOT A MULTIPLE OF PAGE_SIZE, ALL WILL GO TO HELL.
1293 */ 1303 */
1294 lev2mapsize = roundup(howmany(lev3mapsize, NPTEPG), NPTEPG); 1304 lev2mapsize = roundup(howmany(lev3mapsize, NPTEPG), NPTEPG);
1295 lev2map = (pt_entry_t *) 1305 lev2map = (pt_entry_t *)
1296 uvm_pageboot_alloc(sizeof(pt_entry_t) * lev2mapsize); 1306 uvm_pageboot_alloc(sizeof(pt_entry_t) * lev2mapsize);
1297 1307
1298 /* 1308 /*
1299 * Allocate a level 3 PTE table for the kernel. 1309 * Allocate a level 3 PTE table for the kernel.
1300 * Contains lev3mapsize PTEs. 1310 * Contains lev3mapsize PTEs.
1301 */ 1311 */
1302 lev3map = (pt_entry_t *) 1312 lev3map = (pt_entry_t *)
1303 uvm_pageboot_alloc(sizeof(pt_entry_t) * lev3mapsize); 1313 uvm_pageboot_alloc(sizeof(pt_entry_t) * lev3mapsize);
1304 1314
1305 /* 1315 /*
1306 * Set up level 1 page table 1316 * Set up level 1 page table
1307 */ 1317 */
1308 1318
1309 /* Map all of the level 2 pte pages */ 1319 /* Map all of the level 2 pte pages */
1310 for (i = 0; i < howmany(lev2mapsize, NPTEPG); i++) { 1320 for (i = 0; i < howmany(lev2mapsize, NPTEPG); i++) {
1311 pte = (ALPHA_K0SEG_TO_PHYS(((vaddr_t)lev2map) + 1321 pte = (ALPHA_K0SEG_TO_PHYS(((vaddr_t)lev2map) +
1312 (i*PAGE_SIZE)) >> PGSHIFT) << PG_SHIFT; 1322 (i*PAGE_SIZE)) >> PGSHIFT) << PG_SHIFT;
1313 pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED; 1323 pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;
1314 kernel_lev1map[l1pte_index(VM_MIN_KERNEL_ADDRESS + 1324 kernel_lev1map[l1pte_index(VM_MIN_KERNEL_ADDRESS +
1315 (i*PAGE_SIZE*NPTEPG*NPTEPG))] = pte; 1325 (i*PAGE_SIZE*NPTEPG*NPTEPG))] = pte;
1316 } 1326 }
1317 1327
1318 /* Map the virtual page table */ 1328 /* Map the virtual page table */
1319 pte = (ALPHA_K0SEG_TO_PHYS((vaddr_t)kernel_lev1map) >> PGSHIFT) 1329 pte = (ALPHA_K0SEG_TO_PHYS((vaddr_t)kernel_lev1map) >> PGSHIFT)
1320 << PG_SHIFT; 1330 << PG_SHIFT;
1321 pte |= PG_V | PG_KRE | PG_KWE; /* NOTE NO ASM */ 1331 pte |= PG_V | PG_KRE | PG_KWE; /* NOTE NO ASM */
1322 kernel_lev1map[l1pte_index(VPTBASE)] = pte; 1332 kernel_lev1map[l1pte_index(VPTBASE)] = pte;
1323 VPT = (pt_entry_t *)VPTBASE; 1333 VPT = (pt_entry_t *)VPTBASE;
1324 1334
1325 /* 1335 /*
1326 * Set up level 2 page table. 1336 * Set up level 2 page table.
1327 */ 1337 */
1328 /* Map all of the level 3 pte pages */ 1338 /* Map all of the level 3 pte pages */
1329 for (i = 0; i < howmany(lev3mapsize, NPTEPG); i++) { 1339 for (i = 0; i < howmany(lev3mapsize, NPTEPG); i++) {
1330 pte = (ALPHA_K0SEG_TO_PHYS(((vaddr_t)lev3map) + 1340 pte = (ALPHA_K0SEG_TO_PHYS(((vaddr_t)lev3map) +
1331 (i*PAGE_SIZE)) >> PGSHIFT) << PG_SHIFT; 1341 (i*PAGE_SIZE)) >> PGSHIFT) << PG_SHIFT;
1332 pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED; 1342 pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED;
1333 lev2map[l2pte_index(VM_MIN_KERNEL_ADDRESS+ 1343 lev2map[l2pte_index(VM_MIN_KERNEL_ADDRESS+
1334 (i*PAGE_SIZE*NPTEPG))] = pte; 1344 (i*PAGE_SIZE*NPTEPG))] = pte;
1335 } 1345 }
1336 1346
1337 /* Initialize the pmap_growkernel_lock. */ 1347 /* Initialize the pmap_growkernel_lock. */
1338 rw_init(&pmap_growkernel_lock); 1348 rw_init(&pmap_growkernel_lock);
1339 1349
1340 /* 1350 /*
1341 * Set up level three page table (lev3map) 1351 * Set up level three page table (lev3map)
1342 */ 1352 */
1343 /* Nothing to do; it's already zero'd */ 1353 /* Nothing to do; it's already zero'd */
1344 1354
1345 /* 1355 /*
1346 * Initialize the pmap pools and list. 1356 * Initialize the pmap pools and list.
1347 */ 1357 */
1348 pmap_ncpuids = ncpuids; 1358 pmap_ncpuids = ncpuids;
1349 pool_cache_bootstrap(&pmap_pmap_cache, PMAP_SIZEOF(pmap_ncpuids), 1359 pool_cache_bootstrap(&pmap_pmap_cache, PMAP_SIZEOF(pmap_ncpuids),
1350 COHERENCY_UNIT, 0, 0, "pmap", NULL, IPL_NONE, NULL, NULL, NULL); 1360 COHERENCY_UNIT, 0, 0, "pmap", NULL, IPL_NONE, NULL, NULL, NULL);
1351 pool_cache_bootstrap(&pmap_l1pt_cache, PAGE_SIZE, 0, 0, 0, "pmapl1pt", 1361 pool_cache_bootstrap(&pmap_l1pt_cache, PAGE_SIZE, 0, 0, 0, "pmapl1pt",
1352 &pmap_l1pt_allocator, IPL_NONE, pmap_l1pt_ctor, NULL, NULL); 1362 &pmap_l1pt_allocator, IPL_NONE, pmap_l1pt_ctor, NULL, NULL);
1353 pool_cache_bootstrap(&pmap_pv_cache, sizeof(struct pv_entry), 0, 0, 1363 pool_cache_bootstrap(&pmap_pv_cache, sizeof(struct pv_entry), 0, 0,
1354 PR_LARGECACHE, "pmappv", &pmap_pv_page_allocator, IPL_NONE, NULL, 1364 PR_LARGECACHE, "pmappv", &pmap_pv_page_allocator, IPL_NONE, NULL,
1355 NULL, NULL); 1365 NULL, NULL);
1356 1366
1357 TAILQ_INIT(&pmap_all_pmaps); 1367 TAILQ_INIT(&pmap_all_pmaps);
1358 1368
1359 /* Initialize the ASN logic. See also pmap_init_cpu(). */ 1369 /* Initialize the ASN logic. See also pmap_init_cpu(). */
1360 pmap_max_asn = maxasn; 1370 pmap_max_asn = maxasn;
1361 1371
1362 /* 1372 /*
1363 * Initialize the locks. 1373 * Initialize the locks.
1364 */ 1374 */
1365 rw_init(&pmap_main_lock); 1375 rw_init(&pmap_main_lock);
1366 mutex_init(&pmap_all_pmaps_lock, MUTEX_DEFAULT, IPL_NONE); 1376 mutex_init(&pmap_all_pmaps_lock, MUTEX_DEFAULT, IPL_NONE);
1367 for (i = 0; i < __arraycount(pmap_pvh_locks); i++) { 1377 for (i = 0; i < __arraycount(pmap_pvh_locks); i++) {
1368 mutex_init(&pmap_pvh_locks[i].lock, MUTEX_DEFAULT, IPL_NONE); 1378 mutex_init(&pmap_pvh_locks[i].lock, MUTEX_DEFAULT, IPL_NONE);
1369 } 1379 }
1370 for (i = 0; i < __arraycount(pmap_pvh_locks); i++) { 1380 for (i = 0; i < __arraycount(pmap_pvh_locks); i++) {
1371 mutex_init(&pmap_pmap_locks[i].locks.lock, 1381 mutex_init(&pmap_pmap_locks[i].locks.lock,
1372 MUTEX_DEFAULT, IPL_NONE); 1382 MUTEX_DEFAULT, IPL_NONE);
1373 mutex_init(&pmap_pmap_locks[i].locks.activation_lock, 1383 mutex_init(&pmap_pmap_locks[i].locks.activation_lock,
1374 MUTEX_SPIN, IPL_SCHED); 1384 MUTEX_SPIN, IPL_SCHED);
1375 } 1385 }
1376  1386
1377 /* 1387 /*
1378 * This must block any interrupt from which a TLB shootdown 1388 * This must block any interrupt from which a TLB shootdown
1379 * could be issued, but must NOT block IPIs. 1389 * could be issued, but must NOT block IPIs.
1380 */ 1390 */
1381 mutex_init(&tlb_lock, MUTEX_SPIN, IPL_VM); 1391 mutex_init(&tlb_lock, MUTEX_SPIN, IPL_VM);
1382 1392
1383 /* 1393 /*
1384 * Initialize kernel pmap. Note that all kernel mappings 1394 * Initialize kernel pmap. Note that all kernel mappings
1385 * have PG_ASM set, so the ASN doesn't really matter for 1395 * have PG_ASM set, so the ASN doesn't really matter for
1386 * the kernel pmap. Also, since the kernel pmap always 1396 * the kernel pmap. Also, since the kernel pmap always
1387 * references kernel_lev1map, it always has an invalid ASN 1397 * references kernel_lev1map, it always has an invalid ASN
1388 * generation. 1398 * generation.
1389 */ 1399 */
1390 memset(pmap_kernel(), 0, sizeof(struct pmap)); 1400 memset(pmap_kernel(), 0, sizeof(struct pmap));
1391 atomic_store_relaxed(&pmap_kernel()->pm_count, 1); 1401 atomic_store_relaxed(&pmap_kernel()->pm_count, 1);
1392 /* Kernel pmap does not have per-CPU info. */ 1402 /* Kernel pmap does not have per-CPU info. */
1393 TAILQ_INSERT_TAIL(&pmap_all_pmaps, pmap_kernel(), pm_list); 1403 TAILQ_INSERT_TAIL(&pmap_all_pmaps, pmap_kernel(), pm_list);
1394 1404
1395 /* 1405 /*
1396 * Set up lwp0's PCB such that the ptbr points to the right place 1406 * Set up lwp0's PCB such that the ptbr points to the right place
1397 * and has the kernel pmap's (really unused) ASN. 1407 * and has the kernel pmap's (really unused) ASN.
1398 */ 1408 */
1399 pcb = lwp_getpcb(&lwp0); 1409 pcb = lwp_getpcb(&lwp0);
1400 pcb->pcb_hw.apcb_ptbr = 1410 pcb->pcb_hw.apcb_ptbr =
1401 ALPHA_K0SEG_TO_PHYS((vaddr_t)kernel_lev1map) >> PGSHIFT; 1411 ALPHA_K0SEG_TO_PHYS((vaddr_t)kernel_lev1map) >> PGSHIFT;
1402 pcb->pcb_hw.apcb_asn = PMAP_ASN_KERNEL; 1412 pcb->pcb_hw.apcb_asn = PMAP_ASN_KERNEL;
1403 1413
1404 struct cpu_info * const ci = curcpu(); 1414 struct cpu_info * const ci = curcpu();
1405 pmap_init_cpu(ci); 1415 pmap_init_cpu(ci);
1406} 1416}
1407 1417
1408/* 1418/*
1409 * pmap_virtual_space: [ INTERFACE ] 1419 * pmap_virtual_space: [ INTERFACE ]
1410 * 1420 *
1411 * Define the initial bounds of the kernel virtual address space. 1421 * Define the initial bounds of the kernel virtual address space.
1412 */ 1422 */
1413void 1423void
1414pmap_virtual_space(vaddr_t *vstartp, vaddr_t *vendp) 1424pmap_virtual_space(vaddr_t *vstartp, vaddr_t *vendp)
1415{ 1425{
1416 1426
1417 *vstartp = VM_MIN_KERNEL_ADDRESS; /* kernel is in K0SEG */ 1427 *vstartp = VM_MIN_KERNEL_ADDRESS; /* kernel is in K0SEG */
1418 *vendp = VM_MAX_KERNEL_ADDRESS; /* we use pmap_growkernel */ 1428 *vendp = VM_MAX_KERNEL_ADDRESS; /* we use pmap_growkernel */
1419} 1429}
1420 1430
1421/* 1431/*
1422 * pmap_steal_memory: [ INTERFACE ] 1432 * pmap_steal_memory: [ INTERFACE ]
1423 * 1433 *
1424 * Bootstrap memory allocator (alternative to vm_bootstrap_steal_memory()). 1434 * Bootstrap memory allocator (alternative to vm_bootstrap_steal_memory()).
1425 * This function allows for early dynamic memory allocation until the 1435 * This function allows for early dynamic memory allocation until the
1426 * virtual memory system has been bootstrapped. After that point, either 1436 * virtual memory system has been bootstrapped. After that point, either
1427 * kmem_alloc or malloc should be used. This function works by stealing 1437 * kmem_alloc or malloc should be used. This function works by stealing
1428 * pages from the (to be) managed page pool, then implicitly mapping the 1438 * pages from the (to be) managed page pool, then implicitly mapping the
1429 * pages (by using their k0seg addresses) and zeroing them. 1439 * pages (by using their k0seg addresses) and zeroing them.
1430 * 1440 *
1431 * It may be used once the physical memory segments have been pre-loaded 1441 * It may be used once the physical memory segments have been pre-loaded
1432 * into the vm_physmem[] array. Early memory allocation MUST use this 1442 * into the vm_physmem[] array. Early memory allocation MUST use this
1433 * interface! This cannot be used after vm_page_startup(), and will 1443 * interface! This cannot be used after vm_page_startup(), and will
1434 * generate a panic if tried. 1444 * generate a panic if tried.
1435 * 1445 *
1436 * Note that this memory will never be freed, and in essence it is wired 1446 * Note that this memory will never be freed, and in essence it is wired
1437 * down. 1447 * down.
1438 * 1448 *
1439 * We must adjust *vstartp and/or *vendp iff we use address space 1449 * We must adjust *vstartp and/or *vendp iff we use address space
1440 * from the kernel virtual address range defined by pmap_virtual_space(). 1450 * from the kernel virtual address range defined by pmap_virtual_space().
1441 * 1451 *
1442 * Note: no locking is necessary in this function. 1452 * Note: no locking is necessary in this function.
1443 */ 1453 */
1444vaddr_t 1454vaddr_t
1445pmap_steal_memory(vsize_t size, vaddr_t *vstartp, vaddr_t *vendp) 1455pmap_steal_memory(vsize_t size, vaddr_t *vstartp, vaddr_t *vendp)
1446{ 1456{
1447 int npgs; 1457 int npgs;
1448 vaddr_t va; 1458 vaddr_t va;
1449 paddr_t pa; 1459 paddr_t pa;
1450 1460
1451 uvm_physseg_t bank; 1461 uvm_physseg_t bank;
1452 1462
1453 size = round_page(size); 1463 size = round_page(size);
1454 npgs = atop(size); 1464 npgs = atop(size);
1455 1465
1456#if 0 1466#if 0
1457 printf("PSM: size 0x%lx (npgs 0x%x)\n", size, npgs); 1467 printf("PSM: size 0x%lx (npgs 0x%x)\n", size, npgs);
1458#endif 1468#endif
1459 1469
1460 for (bank = uvm_physseg_get_first(); 1470 for (bank = uvm_physseg_get_first();
1461 uvm_physseg_valid_p(bank); 1471 uvm_physseg_valid_p(bank);
1462 bank = uvm_physseg_get_next(bank)) { 1472 bank = uvm_physseg_get_next(bank)) {
1463 if (uvm.page_init_done == true) 1473 if (uvm.page_init_done == true)
1464 panic("pmap_steal_memory: called _after_ bootstrap"); 1474 panic("pmap_steal_memory: called _after_ bootstrap");
1465 1475
1466#if 0 1476#if 0
1467 printf(" bank %d: avail_start 0x%"PRIxPADDR", start 0x%"PRIxPADDR", " 1477 printf(" bank %d: avail_start 0x%"PRIxPADDR", start 0x%"PRIxPADDR", "
1468 "avail_end 0x%"PRIxPADDR"\n", bank, uvm_physseg_get_avail_start(bank), 1478 "avail_end 0x%"PRIxPADDR"\n", bank, uvm_physseg_get_avail_start(bank),
1469 uvm_physseg_get_start(bank), uvm_physseg_get_avail_end(bank)); 1479 uvm_physseg_get_start(bank), uvm_physseg_get_avail_end(bank));
1470#endif 1480#endif
1471 1481
1472 if (uvm_physseg_get_avail_start(bank) != uvm_physseg_get_start(bank) || 1482 if (uvm_physseg_get_avail_start(bank) != uvm_physseg_get_start(bank) ||
1473 uvm_physseg_get_avail_start(bank) >= uvm_physseg_get_avail_end(bank)) 1483 uvm_physseg_get_avail_start(bank) >= uvm_physseg_get_avail_end(bank))
1474 continue; 1484 continue;
1475 1485
1476#if 0 1486#if 0
1477 printf(" avail_end - avail_start = 0x%"PRIxPADDR"\n", 1487 printf(" avail_end - avail_start = 0x%"PRIxPADDR"\n",
1478 uvm_physseg_get_avail_end(bank) - uvm_physseg_get_avail_start(bank)); 1488 uvm_physseg_get_avail_end(bank) - uvm_physseg_get_avail_start(bank));
1479#endif 1489#endif
1480 1490
1481 if (uvm_physseg_get_avail_end(bank) - uvm_physseg_get_avail_start(bank) 1491 if (uvm_physseg_get_avail_end(bank) - uvm_physseg_get_avail_start(bank)
1482 < npgs) 1492 < npgs)
1483 continue; 1493 continue;
1484 1494
1485 /* 1495 /*
1486 * There are enough pages here; steal them! 1496 * There are enough pages here; steal them!
1487 */ 1497 */
1488 pa = ptoa(uvm_physseg_get_start(bank)); 1498 pa = ptoa(uvm_physseg_get_start(bank));
1489 uvm_physseg_unplug(atop(pa), npgs); 1499 uvm_physseg_unplug(atop(pa), npgs);
1490 1500
1491 va = ALPHA_PHYS_TO_K0SEG(pa); 1501 va = ALPHA_PHYS_TO_K0SEG(pa);
1492 memset((void *)va, 0, size); 1502 memset((void *)va, 0, size);
1493 pmap_pages_stolen += npgs; 1503 pmap_pages_stolen += npgs;
1494 return (va); 1504 return (va);
1495 } 1505 }
1496 1506
1497 /* 1507 /*
1498 * If we got here, this was no memory left. 1508 * If we got here, this was no memory left.
1499 */ 1509 */
1500 panic("pmap_steal_memory: no memory to steal"); 1510 panic("pmap_steal_memory: no memory to steal");
1501} 1511}
1502 1512
1503/* 1513/*
1504 * pmap_init: [ INTERFACE ] 1514 * pmap_init: [ INTERFACE ]
1505 * 1515 *
1506 * Initialize the pmap module. Called by vm_init(), to initialize any 1516 * Initialize the pmap module. Called by vm_init(), to initialize any
1507 * structures that the pmap system needs to map virtual memory. 1517 * structures that the pmap system needs to map virtual memory.
1508 * 1518 *
1509 * Note: no locking is necessary in this function. 1519 * Note: no locking is necessary in this function.
1510 */ 1520 */
1511void 1521void
1512pmap_init(void) 1522pmap_init(void)
1513{ 1523{
1514 1524
1515#ifdef DEBUG 1525#ifdef DEBUG
1516 if (pmapdebug & PDB_FOLLOW) 1526 if (pmapdebug & PDB_FOLLOW)
1517 printf("pmap_init()\n"); 1527 printf("pmap_init()\n");
1518#endif 1528#endif
1519 1529
1520 /* initialize protection array */ 1530 /* initialize protection array */
1521 alpha_protection_init(); 1531 alpha_protection_init();
1522 1532
1523 /* Initialize TLB handling. */ 1533 /* Initialize TLB handling. */
1524 pmap_tlb_init(); 1534 pmap_tlb_init();
1525 1535
1526 /* 1536 /*
1527 * Set a low water mark on the pv_entry pool, so that we are 1537 * Set a low water mark on the pv_entry pool, so that we are
1528 * more likely to have these around even in extreme memory 1538 * more likely to have these around even in extreme memory
1529 * starvation. 1539 * starvation.
1530 */ 1540 */
1531 pool_cache_setlowat(&pmap_pv_cache, pmap_pv_lowat); 1541 pool_cache_setlowat(&pmap_pv_cache, pmap_pv_lowat);
1532 1542
1533 /* 1543 /*
1534 * Now it is safe to enable pv entry recording. 1544 * Now it is safe to enable pv entry recording.
1535 */ 1545 */
1536 pmap_initialized = true; 1546 pmap_initialized = true;
1537 1547
1538#if 0 1548#if 0
1539 for (uvm_physseg_t bank = uvm_physseg_get_first(); 1549 for (uvm_physseg_t bank = uvm_physseg_get_first();
1540 uvm_physseg_valid_p(bank); 1550 uvm_physseg_valid_p(bank);
1541 bank = uvm_physseg_get_next(bank)) { 1551 bank = uvm_physseg_get_next(bank)) {
1542 printf("bank %d\n", bank); 1552 printf("bank %d\n", bank);
1543 printf("\tstart = 0x%lx\n", ptoa(uvm_physseg_get_start(bank))); 1553 printf("\tstart = 0x%lx\n", ptoa(uvm_physseg_get_start(bank)));
1544 printf("\tend = 0x%lx\n", ptoa(uvm_physseg_get_end(bank))); 1554 printf("\tend = 0x%lx\n", ptoa(uvm_physseg_get_end(bank)));
1545 printf("\tavail_start = 0x%lx\n", 1555 printf("\tavail_start = 0x%lx\n",
1546 ptoa(uvm_physseg_get_avail_start(bank))); 1556 ptoa(uvm_physseg_get_avail_start(bank)));
1547 printf("\tavail_end = 0x%lx\n", 1557 printf("\tavail_end = 0x%lx\n",
1548 ptoa(uvm_physseg_get_avail_end(bank))); 1558 ptoa(uvm_physseg_get_avail_end(bank)));
1549 } 1559 }
1550#endif 1560#endif
1551} 1561}
1552 1562
1553/* 1563/*
1554 * pmap_create: [ INTERFACE ] 1564 * pmap_create: [ INTERFACE ]
1555 * 1565 *
1556 * Create and return a physical map. 1566 * Create and return a physical map.
1557 * 1567 *
1558 * Note: no locking is necessary in this function. 1568 * Note: no locking is necessary in this function.
1559 */ 1569 */
1560pmap_t 1570pmap_t
1561pmap_create(void) 1571pmap_create(void)
1562{ 1572{
1563 pmap_t pmap; 1573 pmap_t pmap;
1564 pt_entry_t *lev1map; 1574 pt_entry_t *lev1map;
1565 int i; 1575 int i;
1566 1576
1567#ifdef DEBUG 1577#ifdef DEBUG
1568 if (pmapdebug & (PDB_FOLLOW|PDB_CREATE)) 1578 if (pmapdebug & (PDB_FOLLOW|PDB_CREATE))
1569 printf("pmap_create()\n"); 1579 printf("pmap_create()\n");
1570#endif 1580#endif
1571 1581
1572 pmap = pool_cache_get(&pmap_pmap_cache, PR_WAITOK); 1582 pmap = pool_cache_get(&pmap_pmap_cache, PR_WAITOK);
1573 memset(pmap, 0, sizeof(*pmap)); 1583 memset(pmap, 0, sizeof(*pmap));
1574 1584
1575 atomic_store_relaxed(&pmap->pm_count, 1); 1585 atomic_store_relaxed(&pmap->pm_count, 1);
1576 1586
1577 try_again: 1587 try_again:
1578 rw_enter(&pmap_growkernel_lock, RW_READER); 1588 rw_enter(&pmap_growkernel_lock, RW_READER);
1579 1589
1580 lev1map = pool_cache_get(&pmap_l1pt_cache, PR_NOWAIT); 1590 lev1map = pool_cache_get(&pmap_l1pt_cache, PR_NOWAIT);
1581 if (__predict_false(lev1map == NULL)) { 1591 if (__predict_false(lev1map == NULL)) {
1582 rw_exit(&pmap_growkernel_lock); 1592 rw_exit(&pmap_growkernel_lock);
1583 (void) kpause("pmap_create", false, hz >> 2, NULL); 1593 (void) kpause("pmap_create", false, hz >> 2, NULL);
1584 goto try_again; 1594 goto try_again;
1585 } 1595 }
1586 1596
1587 /* 1597 /*
1588 * There are only kernel mappings at this point; give the pmap 1598 * There are only kernel mappings at this point; give the pmap
1589 * the kernel ASN. This will be initialized to correct values 1599 * the kernel ASN. This will be initialized to correct values
1590 * when the pmap is activated. 1600 * when the pmap is activated.
1591 * 1601 *
1592 * We stash a pointer to the pmap's lev1map in each CPU's 1602 * We stash a pointer to the pmap's lev1map in each CPU's
1593 * private data. It remains constant for the life of the 1603 * private data. It remains constant for the life of the
1594 * pmap, and gives us more room in the shared pmap structure. 1604 * pmap, and gives us more room in the shared pmap structure.
1595 */ 1605 */
1596 for (i = 0; i < pmap_ncpuids; i++) { 1606 for (i = 0; i < pmap_ncpuids; i++) {
1597 pmap->pm_percpu[i].pmc_asn = PMAP_ASN_KERNEL; 1607 pmap->pm_percpu[i].pmc_asn = PMAP_ASN_KERNEL;
1598 pmap->pm_percpu[i].pmc_asngen = PMAP_ASNGEN_INVALID; 1608 pmap->pm_percpu[i].pmc_asngen = PMAP_ASNGEN_INVALID;
1599 pmap->pm_percpu[i].pmc_lev1map = lev1map; 1609 pmap->pm_percpu[i].pmc_lev1map = lev1map;
1600 } 1610 }
1601 1611
1602 mutex_enter(&pmap_all_pmaps_lock); 1612 mutex_enter(&pmap_all_pmaps_lock);
1603 TAILQ_INSERT_TAIL(&pmap_all_pmaps, pmap, pm_list); 1613 TAILQ_INSERT_TAIL(&pmap_all_pmaps, pmap, pm_list);
1604 mutex_exit(&pmap_all_pmaps_lock); 1614 mutex_exit(&pmap_all_pmaps_lock);
1605 1615
1606 rw_exit(&pmap_growkernel_lock); 1616 rw_exit(&pmap_growkernel_lock);
1607 1617
1608 return (pmap); 1618 return (pmap);
1609} 1619}
1610 1620
1611/* 1621/*
1612 * pmap_destroy: [ INTERFACE ] 1622 * pmap_destroy: [ INTERFACE ]
1613 * 1623 *
1614 * Drop the reference count on the specified pmap, releasing 1624 * Drop the reference count on the specified pmap, releasing
1615 * all resources if the reference count drops to zero. 1625 * all resources if the reference count drops to zero.
1616 */ 1626 */
1617void 1627void
1618pmap_destroy(pmap_t pmap) 1628pmap_destroy(pmap_t pmap)
1619{ 1629{
1620 1630
1621#ifdef DEBUG 1631#ifdef DEBUG
1622 if (pmapdebug & PDB_FOLLOW) 1632 if (pmapdebug & PDB_FOLLOW)
1623 printf("pmap_destroy(%p)\n", pmap); 1633 printf("pmap_destroy(%p)\n", pmap);
1624#endif 1634#endif
1625 1635
1626 PMAP_MP(membar_exit()); 1636 PMAP_MP(membar_exit());
1627 KASSERT(atomic_load_relaxed(&pmap->pm_count) > 0); 1637 KASSERT(atomic_load_relaxed(&pmap->pm_count) > 0);
1628 if (atomic_dec_uint_nv(&pmap->pm_count) > 0) 1638 if (atomic_dec_uint_nv(&pmap->pm_count) > 0)
1629 return; 1639 return;
1630 1640
1631 pt_entry_t *lev1map = pmap_lev1map(pmap); 1641 pt_entry_t *lev1map = pmap_lev1map(pmap);
1632 int i; 1642 int i;
1633 1643
1634 rw_enter(&pmap_growkernel_lock, RW_READER); 1644 rw_enter(&pmap_growkernel_lock, RW_READER);
1635 1645
1636 /* 1646 /*
1637 * Remove it from the global list of all pmaps. 1647 * Remove it from the global list of all pmaps.
1638 */ 1648 */
1639 mutex_enter(&pmap_all_pmaps_lock); 1649 mutex_enter(&pmap_all_pmaps_lock);
1640 TAILQ_REMOVE(&pmap_all_pmaps, pmap, pm_list); 1650 TAILQ_REMOVE(&pmap_all_pmaps, pmap, pm_list);
1641 mutex_exit(&pmap_all_pmaps_lock); 1651 mutex_exit(&pmap_all_pmaps_lock);
1642 1652
1643 pool_cache_put(&pmap_l1pt_cache, lev1map); 1653 pool_cache_put(&pmap_l1pt_cache, lev1map);
1644#ifdef DIAGNOSTIC 1654#ifdef DIAGNOSTIC
1645 for (i = 0; i < pmap_ncpuids; i++) { 1655 for (i = 0; i < pmap_ncpuids; i++) {
1646 pmap->pm_percpu[i].pmc_lev1map = (pt_entry_t *)0xdeadbeefUL; 1656 pmap->pm_percpu[i].pmc_lev1map = (pt_entry_t *)0xdeadbeefUL;
1647 } 1657 }
1648#endif /* DIAGNOSTIC */ 1658#endif /* DIAGNOSTIC */
1649 1659
1650 rw_exit(&pmap_growkernel_lock); 1660 rw_exit(&pmap_growkernel_lock);
1651 1661
1652 pool_cache_put(&pmap_pmap_cache, pmap); 1662 pool_cache_put(&pmap_pmap_cache, pmap);
1653} 1663}
1654 1664
1655/* 1665/*
1656 * pmap_reference: [ INTERFACE ] 1666 * pmap_reference: [ INTERFACE ]
1657 * 1667 *
1658 * Add a reference to the specified pmap. 1668 * Add a reference to the specified pmap.
1659 */ 1669 */
1660void 1670void
1661pmap_reference(pmap_t pmap) 1671pmap_reference(pmap_t pmap)
1662{ 1672{
1663 unsigned int newcount __diagused; 1673 unsigned int newcount __diagused;
1664 1674
1665#ifdef DEBUG 1675#ifdef DEBUG
1666 if (pmapdebug & PDB_FOLLOW) 1676 if (pmapdebug & PDB_FOLLOW)
1667 printf("pmap_reference(%p)\n", pmap); 1677 printf("pmap_reference(%p)\n", pmap);
1668#endif 1678#endif
1669 1679
1670 newcount = atomic_inc_uint_nv(&pmap->pm_count); 1680 newcount = atomic_inc_uint_nv(&pmap->pm_count);
1671 KASSERT(newcount != 0); 1681 KASSERT(newcount != 0);
1672 PMAP_MP(membar_enter()); 1682 PMAP_MP(membar_enter());
1673} 1683}
1674 1684
1675/* 1685/*
1676 * pmap_remove: [ INTERFACE ] 1686 * pmap_remove: [ INTERFACE ]
1677 * 1687 *
1678 * Remove the given range of addresses from the specified map. 1688 * Remove the given range of addresses from the specified map.
1679 * 1689 *
1680 * It is assumed that the start and end are properly 1690 * It is assumed that the start and end are properly
1681 * rounded to the page size. 1691 * rounded to the page size.
1682 */ 1692 */
1683static void 1693static void
1684pmap_remove_internal(pmap_t pmap, vaddr_t sva, vaddr_t eva, 1694pmap_remove_internal(pmap_t pmap, vaddr_t sva, vaddr_t eva,
1685 struct pmap_tlb_context * const tlbctx) 1695 struct pmap_tlb_context * const tlbctx)
1686{ 1696{
1687 pt_entry_t *l1pte, *l2pte, *l3pte; 1697 pt_entry_t *l1pte, *l2pte, *l3pte;
1688 pt_entry_t *saved_l2pte, *saved_l3pte; 1698 pt_entry_t *saved_l2pte, *saved_l3pte;
1689 vaddr_t l1eva, l2eva, l3vptva; 1699 vaddr_t l1eva, l2eva, l3vptva;
1690 pt_entry_t pte_bits; 1700 pt_entry_t pte_bits;
1691 1701
1692#ifdef DEBUG 1702#ifdef DEBUG
1693 if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT)) 1703 if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT))
1694 printf("pmap_remove(%p, %lx, %lx)\n", pmap, sva, eva); 1704 printf("pmap_remove(%p, %lx, %lx)\n", pmap, sva, eva);
1695#endif 1705#endif
1696 1706
1697 /* 1707 /*
1698 * If this is the kernel pmap, we can use a faster method 1708 * If this is the kernel pmap, we can use a faster method
1699 * for accessing the PTEs (since the PT pages are always 1709 * for accessing the PTEs (since the PT pages are always
1700 * resident). 1710 * resident).
1701 * 1711 *
1702 * Note that this routine should NEVER be called from an 1712 * Note that this routine should NEVER be called from an
1703 * interrupt context; pmap_kremove() is used for that. 1713 * interrupt context; pmap_kremove() is used for that.
1704 */ 1714 */
1705 if (pmap == pmap_kernel()) { 1715 if (pmap == pmap_kernel()) {
1706 PMAP_MAP_TO_HEAD_LOCK(); 1716 PMAP_MAP_TO_HEAD_LOCK();
1707 PMAP_LOCK(pmap); 1717 PMAP_LOCK(pmap);
1708 1718
1709 while (sva < eva) { 1719 while (sva < eva) {
1710 l3pte = PMAP_KERNEL_PTE(sva); 1720 l3pte = PMAP_KERNEL_PTE(sva);
1711 if (pmap_pte_v(l3pte)) { 1721 if (pmap_pte_v(l3pte)) {
1712 pte_bits = pmap_remove_mapping(pmap, sva, 1722 pte_bits = pmap_remove_mapping(pmap, sva,
1713 l3pte, true, NULL, tlbctx); 1723 l3pte, true, NULL, tlbctx);
1714 pmap_tlb_shootdown(pmap, sva, pte_bits, 1724 pmap_tlb_shootdown(pmap, sva, pte_bits,
1715 tlbctx); 1725 tlbctx);
1716 } 1726 }
1717 sva += PAGE_SIZE; 1727 sva += PAGE_SIZE;
1718 } 1728 }
1719 1729
1720 PMAP_MAP_TO_HEAD_UNLOCK(); 1730 PMAP_MAP_TO_HEAD_UNLOCK();
1721 PMAP_UNLOCK(pmap); 1731 PMAP_UNLOCK(pmap);
1722 pmap_tlb_shootnow(tlbctx); 1732 pmap_tlb_shootnow(tlbctx);
1723 pmap_tlb_ptpage_drain(tlbctx); 1733 /* kernel PT pages are never freed. */
 1734 KASSERT(LIST_EMPTY(&tlbctx->t_freeptq));
1724 TLB_COUNT(reason_remove_kernel); 1735 TLB_COUNT(reason_remove_kernel);
1725 1736
1726 return; 1737 return;
1727 } 1738 }
1728 1739
1729 pt_entry_t * const lev1map = pmap_lev1map(pmap); 1740 pt_entry_t * const lev1map = pmap_lev1map(pmap);
1730 1741
1731 KASSERT(sva < VM_MAXUSER_ADDRESS); 1742 KASSERT(sva < VM_MAXUSER_ADDRESS);
1732 KASSERT(eva <= VM_MAXUSER_ADDRESS); 1743 KASSERT(eva <= VM_MAXUSER_ADDRESS);
1733 KASSERT(lev1map != kernel_lev1map); 1744 KASSERT(lev1map != kernel_lev1map);
1734 1745
1735 PMAP_MAP_TO_HEAD_LOCK(); 1746 PMAP_MAP_TO_HEAD_LOCK();
1736 PMAP_LOCK(pmap); 1747 PMAP_LOCK(pmap);
1737 1748
1738 l1pte = pmap_l1pte(lev1map, sva); 1749 l1pte = pmap_l1pte(lev1map, sva);
1739 1750
1740 for (; sva < eva; sva = l1eva, l1pte++) { 1751 for (; sva < eva; sva = l1eva, l1pte++) {
1741 l1eva = alpha_trunc_l1seg(sva) + ALPHA_L1SEG_SIZE; 1752 l1eva = alpha_trunc_l1seg(sva) + ALPHA_L1SEG_SIZE;
1742 if (pmap_pte_v(l1pte)) { 1753 if (pmap_pte_v(l1pte)) {
1743 saved_l2pte = l2pte = pmap_l2pte(lev1map, sva, l1pte); 1754 saved_l2pte = l2pte = pmap_l2pte(lev1map, sva, l1pte);
1744 1755
1745 /* 1756 /*
1746 * Add a reference to the L2 table so it won't 1757 * Add a reference to the L2 table so it won't
1747 * get removed from under us. 1758 * get removed from under us.
1748 */ 1759 */
1749 pmap_physpage_addref(saved_l2pte); 1760 pmap_physpage_addref(saved_l2pte);
1750 1761
1751 for (; sva < l1eva && sva < eva; sva = l2eva, l2pte++) { 1762 for (; sva < l1eva && sva < eva; sva = l2eva, l2pte++) {
1752 l2eva = 1763 l2eva =
1753 alpha_trunc_l2seg(sva) + ALPHA_L2SEG_SIZE; 1764 alpha_trunc_l2seg(sva) + ALPHA_L2SEG_SIZE;
1754 if (pmap_pte_v(l2pte)) { 1765 if (pmap_pte_v(l2pte)) {
1755 saved_l3pte = l3pte = 1766 saved_l3pte = l3pte =
1756 pmap_l3pte(lev1map, sva, l2pte); 1767 pmap_l3pte(lev1map, sva, l2pte);
1757 1768
1758 /* 1769 /*
1759 * Add a reference to the L3 table so 1770 * Add a reference to the L3 table so
1760 * it won't get removed from under us. 1771 * it won't get removed from under us.
1761 */ 1772 */
1762 pmap_physpage_addref(saved_l3pte); 1773 pmap_physpage_addref(saved_l3pte);
1763 1774
1764 /* 1775 /*
1765 * Remember this sva; if the L3 table 1776 * Remember this sva; if the L3 table
1766 * gets removed, we need to invalidate 1777 * gets removed, we need to invalidate
1767 * the VPT TLB entry for it. 1778 * the VPT TLB entry for it.
1768 */ 1779 */
1769 l3vptva = sva; 1780 l3vptva = sva;
1770 1781
1771 for (; sva < l2eva && sva < eva; 1782 for (; sva < l2eva && sva < eva;
1772 sva += PAGE_SIZE, l3pte++) { 1783 sva += PAGE_SIZE, l3pte++) {
1773 if (!pmap_pte_v(l3pte)) { 1784 if (!pmap_pte_v(l3pte)) {
1774 continue; 1785 continue;
1775 } 1786 }
1776 pte_bits = 1787 pte_bits =
1777 pmap_remove_mapping( 1788 pmap_remove_mapping(
1778 pmap, sva, 1789 pmap, sva,
1779 l3pte, true, 1790 l3pte, true,
1780 NULL, tlbctx); 1791 NULL, tlbctx);
1781 pmap_tlb_shootdown(pmap, 1792 pmap_tlb_shootdown(pmap,
1782 sva, pte_bits, tlbctx); 1793 sva, pte_bits, tlbctx);
1783 } 1794 }
1784 1795
1785 /* 1796 /*
1786 * Remove the reference to the L3 1797 * Remove the reference to the L3
1787 * table that we added above. This 1798 * table that we added above. This
1788 * may free the L3 table. 1799 * may free the L3 table.
1789 */ 1800 */
1790 pmap_l3pt_delref(pmap, l3vptva, 1801 pmap_l3pt_delref(pmap, l3vptva,
1791 saved_l3pte, tlbctx); 1802 saved_l3pte, tlbctx);
1792 } 1803 }
1793 } 1804 }
1794 1805
1795 /* 1806 /*
1796 * Remove the reference to the L2 table that we 1807 * Remove the reference to the L2 table that we
1797 * added above. This may free the L2 table. 1808 * added above. This may free the L2 table.
1798 */ 1809 */
1799 pmap_l2pt_delref(pmap, l1pte, saved_l2pte, tlbctx); 1810 pmap_l2pt_delref(pmap, l1pte, saved_l2pte, tlbctx);
1800 } 1811 }
1801 } 1812 }
1802 1813
1803 PMAP_MAP_TO_HEAD_UNLOCK(); 1814 PMAP_MAP_TO_HEAD_UNLOCK();
1804 PMAP_UNLOCK(pmap); 1815 PMAP_UNLOCK(pmap);
1805 pmap_tlb_shootnow(tlbctx); 1816 pmap_tlb_shootnow(tlbctx);
1806 pmap_tlb_ptpage_drain(tlbctx); 1817 pmap_tlb_ptpage_drain(tlbctx);
1807 TLB_COUNT(reason_remove_user); 1818 TLB_COUNT(reason_remove_user);
1808} 1819}
1809 1820
1810void 1821void
1811pmap_remove(pmap_t pmap, vaddr_t sva, vaddr_t eva) 1822pmap_remove(pmap_t pmap, vaddr_t sva, vaddr_t eva)
1812{ 1823{
1813 struct pmap_tlb_context tlbctx; 1824 struct pmap_tlb_context tlbctx;
1814 1825
1815 pmap_tlb_context_init(&tlbctx, 0); 1826 pmap_tlb_context_init(&tlbctx, 0);
1816 pmap_remove_internal(pmap, sva, eva, &tlbctx); 1827 pmap_remove_internal(pmap, sva, eva, &tlbctx);
1817} 1828}
1818 1829
1819/* 1830/*
1820 * pmap_page_protect: [ INTERFACE ] 1831 * pmap_page_protect: [ INTERFACE ]
1821 * 1832 *
1822 * Lower the permission for all mappings to a given page to 1833 * Lower the permission for all mappings to a given page to
1823 * the permissions specified. 1834 * the permissions specified.
1824 */ 1835 */
1825void 1836void
1826pmap_page_protect(struct vm_page *pg, vm_prot_t prot) 1837pmap_page_protect(struct vm_page *pg, vm_prot_t prot)
1827{ 1838{
1828 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 1839 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
1829 pv_entry_t pv, nextpv; 1840 pv_entry_t pv, nextpv;
1830 pt_entry_t opte; 1841 pt_entry_t opte;
1831 kmutex_t *lock; 1842 kmutex_t *lock;
1832 struct pmap_tlb_context tlbctx; 1843 struct pmap_tlb_context tlbctx;
1833 1844
1834#ifdef DEBUG 1845#ifdef DEBUG
1835 paddr_t pa = VM_PAGE_TO_PHYS(pg); 1846 paddr_t pa = VM_PAGE_TO_PHYS(pg);
1836 1847
1837 1848
1838 if ((pmapdebug & (PDB_FOLLOW|PDB_PROTECT)) || 1849 if ((pmapdebug & (PDB_FOLLOW|PDB_PROTECT)) ||
1839 (prot == VM_PROT_NONE && (pmapdebug & PDB_REMOVE))) 1850 (prot == VM_PROT_NONE && (pmapdebug & PDB_REMOVE)))
1840 printf("pmap_page_protect(%p, %x)\n", pg, prot); 1851 printf("pmap_page_protect(%p, %x)\n", pg, prot);
1841#endif 1852#endif
1842 1853
1843 pmap_tlb_context_init(&tlbctx, TLB_CTX_F_PV); 1854 pmap_tlb_context_init(&tlbctx, TLB_CTX_F_PV);
1844 1855
1845 switch (prot) { 1856 switch (prot) {
1846 case VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE: 1857 case VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE:
1847 case VM_PROT_READ|VM_PROT_WRITE: 1858 case VM_PROT_READ|VM_PROT_WRITE:
1848 return; 1859 return;
1849 1860
1850 /* copy_on_write */ 1861 /* copy_on_write */
1851 case VM_PROT_READ|VM_PROT_EXECUTE: 1862 case VM_PROT_READ|VM_PROT_EXECUTE:
1852 case VM_PROT_READ: 1863 case VM_PROT_READ:
1853 PMAP_HEAD_TO_MAP_LOCK(); 1864 PMAP_HEAD_TO_MAP_LOCK();
1854 lock = pmap_pvh_lock(pg); 1865 lock = pmap_pvh_lock(pg);
1855 mutex_enter(lock); 1866 mutex_enter(lock);
1856 for (pv = md->pvh_list; pv != NULL; pv = pv->pv_next) { 1867 for (pv = md->pvh_list; pv != NULL; pv = pv->pv_next) {
1857 PMAP_LOCK(pv->pv_pmap); 1868 PMAP_LOCK(pv->pv_pmap);
1858 opte = atomic_load_relaxed(pv->pv_pte); 1869 opte = atomic_load_relaxed(pv->pv_pte);
1859 if (opte & (PG_KWE | PG_UWE)) { 1870 if (opte & (PG_KWE | PG_UWE)) {
1860 atomic_store_relaxed(pv->pv_pte, 1871 atomic_store_relaxed(pv->pv_pte,
1861 opte & ~(PG_KWE | PG_UWE)); 1872 opte & ~(PG_KWE | PG_UWE));
1862 pmap_tlb_shootdown_pv(pv->pv_pmap, pv->pv_va, 1873 pmap_tlb_shootdown_pv(pv->pv_pmap, pv->pv_va,
1863 opte, &tlbctx); 1874 opte, &tlbctx);
1864 } 1875 }
1865 PMAP_UNLOCK(pv->pv_pmap); 1876 PMAP_UNLOCK(pv->pv_pmap);
1866 } 1877 }
1867 mutex_exit(lock); 1878 mutex_exit(lock);
1868 PMAP_HEAD_TO_MAP_UNLOCK(); 1879 PMAP_HEAD_TO_MAP_UNLOCK();
1869 pmap_tlb_shootnow(&tlbctx); 1880 pmap_tlb_shootnow(&tlbctx);
1870 TLB_COUNT(reason_page_protect_read); 1881 TLB_COUNT(reason_page_protect_read);
1871 return; 1882 return;
1872 1883
1873 /* remove_all */ 1884 /* remove_all */
1874 default: 1885 default:
1875 break; 1886 break;
1876 } 1887 }
1877 1888
1878 PMAP_HEAD_TO_MAP_LOCK(); 1889 PMAP_HEAD_TO_MAP_LOCK();
1879 lock = pmap_pvh_lock(pg); 1890 lock = pmap_pvh_lock(pg);
1880 mutex_enter(lock); 1891 mutex_enter(lock);
1881 for (pv = md->pvh_list; pv != NULL; pv = nextpv) { 1892 for (pv = md->pvh_list; pv != NULL; pv = nextpv) {
1882 pt_entry_t pte_bits; 1893 pt_entry_t pte_bits;
1883 pmap_t pmap; 1894 pmap_t pmap;
1884 vaddr_t va; 1895 vaddr_t va;
1885 1896
1886 nextpv = pv->pv_next; 1897 nextpv = pv->pv_next;
1887 1898
1888 PMAP_LOCK(pv->pv_pmap); 1899 PMAP_LOCK(pv->pv_pmap);
1889 pmap = pv->pv_pmap; 1900 pmap = pv->pv_pmap;
1890 va = pv->pv_va; 1901 va = pv->pv_va;
1891 pte_bits = pmap_remove_mapping(pmap, va, pv->pv_pte, 1902 pte_bits = pmap_remove_mapping(pmap, va, pv->pv_pte,
1892 false, NULL, &tlbctx); 1903 false, NULL, &tlbctx);
1893 pmap_tlb_shootdown_pv(pmap, va, pte_bits, &tlbctx); 1904 pmap_tlb_shootdown_pv(pmap, va, pte_bits, &tlbctx);
1894 PMAP_UNLOCK(pv->pv_pmap); 1905 PMAP_UNLOCK(pv->pv_pmap);
1895 } 1906 }
1896 mutex_exit(lock); 1907 mutex_exit(lock);
1897 PMAP_HEAD_TO_MAP_UNLOCK(); 1908 PMAP_HEAD_TO_MAP_UNLOCK();
1898 pmap_tlb_shootnow(&tlbctx); 1909 pmap_tlb_shootnow(&tlbctx);
1899 pmap_tlb_ptpage_drain(&tlbctx); 1910 pmap_tlb_ptpage_drain(&tlbctx);
1900 TLB_COUNT(reason_page_protect_none); 1911 TLB_COUNT(reason_page_protect_none);
1901} 1912}
1902 1913
1903/* 1914/*
1904 * pmap_protect: [ INTERFACE ] 1915 * pmap_protect: [ INTERFACE ]
1905 * 1916 *
1906 * Set the physical protection on the specified range of this map 1917 * Set the physical protection on the specified range of this map
1907 * as requested. 1918 * as requested.
1908 */ 1919 */
1909void 1920void
1910pmap_protect(pmap_t pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot) 1921pmap_protect(pmap_t pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot)
1911{ 1922{
1912 pt_entry_t *l1pte, *l2pte, *l3pte, opte; 1923 pt_entry_t *l1pte, *l2pte, *l3pte, opte;
1913 vaddr_t l1eva, l2eva; 1924 vaddr_t l1eva, l2eva;
1914 struct pmap_tlb_context tlbctx; 1925 struct pmap_tlb_context tlbctx;
1915 1926
1916#ifdef DEBUG 1927#ifdef DEBUG
1917 if (pmapdebug & (PDB_FOLLOW|PDB_PROTECT)) 1928 if (pmapdebug & (PDB_FOLLOW|PDB_PROTECT))
1918 printf("pmap_protect(%p, %lx, %lx, %x)\n", 1929 printf("pmap_protect(%p, %lx, %lx, %x)\n",
1919 pmap, sva, eva, prot); 1930 pmap, sva, eva, prot);
1920#endif 1931#endif
1921 1932
1922 pmap_tlb_context_init(&tlbctx, 0); 1933 pmap_tlb_context_init(&tlbctx, 0);
1923 1934
1924 if ((prot & VM_PROT_READ) == VM_PROT_NONE) { 1935 if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
1925 pmap_remove_internal(pmap, sva, eva, &tlbctx); 1936 pmap_remove_internal(pmap, sva, eva, &tlbctx);
1926 return; 1937 return;
1927 } 1938 }
1928 1939
1929 const pt_entry_t bits = pte_prot(pmap, prot); 1940 const pt_entry_t bits = pte_prot(pmap, prot);
1930 pt_entry_t * const lev1map = pmap_lev1map(pmap); 1941 pt_entry_t * const lev1map = pmap_lev1map(pmap);
1931 1942
1932 PMAP_LOCK(pmap); 1943 PMAP_LOCK(pmap);
1933 1944
1934 l1pte = pmap_l1pte(lev1map, sva); 1945 l1pte = pmap_l1pte(lev1map, sva);
1935 for (; sva < eva; sva = l1eva, l1pte++) { 1946 for (; sva < eva; sva = l1eva, l1pte++) {
1936 l1eva = alpha_trunc_l1seg(sva) + ALPHA_L1SEG_SIZE; 1947 l1eva = alpha_trunc_l1seg(sva) + ALPHA_L1SEG_SIZE;
1937 if (pmap_pte_v(l1pte)) { 1948 if (pmap_pte_v(l1pte)) {
1938 l2pte = pmap_l2pte(lev1map, sva, l1pte); 1949 l2pte = pmap_l2pte(lev1map, sva, l1pte);
1939 for (; sva < l1eva && sva < eva; sva = l2eva, l2pte++) { 1950 for (; sva < l1eva && sva < eva; sva = l2eva, l2pte++) {
1940 l2eva = 1951 l2eva =
1941 alpha_trunc_l2seg(sva) + ALPHA_L2SEG_SIZE; 1952 alpha_trunc_l2seg(sva) + ALPHA_L2SEG_SIZE;
1942 if (pmap_pte_v(l2pte)) { 1953 if (pmap_pte_v(l2pte)) {
1943 l3pte = pmap_l3pte(lev1map, sva, l2pte); 1954 l3pte = pmap_l3pte(lev1map, sva, l2pte);
1944 for (; sva < l2eva && sva < eva; 1955 for (; sva < l2eva && sva < eva;
1945 sva += PAGE_SIZE, l3pte++) { 1956 sva += PAGE_SIZE, l3pte++) {
1946 if (pmap_pte_v(l3pte) && 1957 if (pmap_pte_v(l3pte) &&
1947 pmap_pte_prot_chg(l3pte, 1958 pmap_pte_prot_chg(l3pte,
1948 bits)) { 1959 bits)) {
1949 opte = atomic_load_relaxed(l3pte); 1960 opte = atomic_load_relaxed(l3pte);
1950 pmap_pte_set_prot(l3pte, 1961 pmap_pte_set_prot(l3pte,
1951 bits); 1962 bits);
1952 pmap_tlb_shootdown(pmap, 1963 pmap_tlb_shootdown(pmap,
1953 sva, opte, &tlbctx); 1964 sva, opte, &tlbctx);
1954 } 1965 }
1955 } 1966 }
1956 } 1967 }
1957 } 1968 }
1958 } 1969 }
1959 } 1970 }
1960 1971
1961 PMAP_UNLOCK(pmap); 1972 PMAP_UNLOCK(pmap);
1962 pmap_tlb_shootnow(&tlbctx); 1973 pmap_tlb_shootnow(&tlbctx);
1963 TLB_COUNT(reason_protect); 1974 TLB_COUNT(reason_protect);
1964} 1975}
1965 1976
1966/* 1977/*
1967 * pmap_enter_tlb_shootdown: 1978 * pmap_enter_tlb_shootdown:
1968 * 1979 *
1969 * Carry out a TLB shootdown on behalf of a pmap_enter() 1980 * Carry out a TLB shootdown on behalf of a pmap_enter()
1970 * or a pmap_kenter_pa(). This is factored out separately 1981 * or a pmap_kenter_pa(). This is factored out separately
1971 * because we expect it to be not a common case. 1982 * because we expect it to be not a common case.
1972 */ 1983 */
1973static void __noinline 1984static void __noinline
1974pmap_enter_tlb_shootdown(pmap_t const pmap, vaddr_t const va, 1985pmap_enter_tlb_shootdown(pmap_t const pmap, vaddr_t const va,
1975 pt_entry_t const pte_bits, bool locked) 1986 pt_entry_t const pte_bits, bool locked)
1976{ 1987{
1977 struct pmap_tlb_context tlbctx; 1988 struct pmap_tlb_context tlbctx;
1978 1989
1979 pmap_tlb_context_init(&tlbctx, 0); 1990 pmap_tlb_context_init(&tlbctx, 0);
1980 pmap_tlb_shootdown(pmap, va, pte_bits, &tlbctx); 1991 pmap_tlb_shootdown(pmap, va, pte_bits, &tlbctx);
1981 if (locked) { 1992 if (locked) {
1982 PMAP_UNLOCK(pmap); 1993 PMAP_UNLOCK(pmap);
1983 } 1994 }
1984 pmap_tlb_shootnow(&tlbctx); 1995 pmap_tlb_shootnow(&tlbctx);
1985} 1996}
1986 1997
1987/* 1998/*
1988 * pmap_enter_l2pt_delref: 1999 * pmap_enter_l2pt_delref:
1989 * 2000 *
1990 * Release a reference on an L2 PT page for pmap_enter(). 2001 * Release a reference on an L2 PT page for pmap_enter().
1991 * This is factored out separately becacause we expect it 2002 * This is factored out separately becacause we expect it
1992 * to be a rare case. 2003 * to be a rare case.
1993 */ 2004 */
1994static void __noinline 2005static void __noinline
1995pmap_enter_l2pt_delref(pmap_t const pmap, pt_entry_t * const l1pte, 2006pmap_enter_l2pt_delref(pmap_t const pmap, pt_entry_t * const l1pte,
1996 pt_entry_t * const l2pte) 2007 pt_entry_t * const l2pte)
1997{ 2008{
1998 struct pmap_tlb_context tlbctx; 2009 struct pmap_tlb_context tlbctx;
1999 2010
2000 /* 2011 /*
2001 * PALcode may have tried to service a TLB miss with 2012 * PALcode may have tried to service a TLB miss with
2002 * this L2 PTE, so we need to make sure we don't actully 2013 * this L2 PTE, so we need to make sure we don't actully
2003 * free the PT page untl we've shot down any TLB entries 2014 * free the PT page untl we've shot down any TLB entries
2004 * for this VPT index. 2015 * for this VPT index.
2005 */ 2016 */
2006 2017
2007 pmap_tlb_context_init(&tlbctx, 0); 2018 pmap_tlb_context_init(&tlbctx, 0);
2008 pmap_l2pt_delref(pmap, l1pte, l2pte, &tlbctx); 2019 pmap_l2pt_delref(pmap, l1pte, l2pte, &tlbctx);
2009 PMAP_UNLOCK(pmap); 2020 PMAP_UNLOCK(pmap);
2010 pmap_tlb_shootnow(&tlbctx); 2021 pmap_tlb_shootnow(&tlbctx);
2011 pmap_tlb_ptpage_drain(&tlbctx); 2022 pmap_tlb_ptpage_drain(&tlbctx);
2012 TLB_COUNT(reason_enter_l2pt_delref); 2023 TLB_COUNT(reason_enter_l2pt_delref);
2013} 2024}
2014 2025
2015/* 2026/*
2016 * pmap_enter_l3pt_delref: 2027 * pmap_enter_l3pt_delref:
2017 * 2028 *
2018 * Release a reference on an L3 PT page for pmap_enter(). 2029 * Release a reference on an L3 PT page for pmap_enter().
2019 * This is factored out separately becacause we expect it 2030 * This is factored out separately becacause we expect it
2020 * to be a rare case. 2031 * to be a rare case.
2021 */ 2032 */
2022static void __noinline 2033static void __noinline
2023pmap_enter_l3pt_delref(pmap_t const pmap, vaddr_t const va, 2034pmap_enter_l3pt_delref(pmap_t const pmap, vaddr_t const va,
2024 pt_entry_t * const pte) 2035 pt_entry_t * const pte)
2025{ 2036{
2026 struct pmap_tlb_context tlbctx; 2037 struct pmap_tlb_context tlbctx;
2027 2038
2028 /* 2039 /*
2029 * PALcode may have tried to service a TLB miss with 2040 * PALcode may have tried to service a TLB miss with
2030 * this PTE, so we need to make sure we don't actully 2041 * this PTE, so we need to make sure we don't actully
2031 * free the PT page untl we've shot down any TLB entries 2042 * free the PT page untl we've shot down any TLB entries
2032 * for this VPT index. 2043 * for this VPT index.
2033 */ 2044 */
2034 2045
2035 pmap_tlb_context_init(&tlbctx, 0); 2046 pmap_tlb_context_init(&tlbctx, 0);
2036 pmap_l3pt_delref(pmap, va, pte, &tlbctx); 2047 pmap_l3pt_delref(pmap, va, pte, &tlbctx);
2037 PMAP_UNLOCK(pmap); 2048 PMAP_UNLOCK(pmap);
2038 pmap_tlb_shootnow(&tlbctx); 2049 pmap_tlb_shootnow(&tlbctx);
2039 pmap_tlb_ptpage_drain(&tlbctx); 2050 pmap_tlb_ptpage_drain(&tlbctx);
2040 TLB_COUNT(reason_enter_l3pt_delref); 2051 TLB_COUNT(reason_enter_l3pt_delref);
2041} 2052}
2042 2053
2043/* 2054/*
2044 * pmap_enter: [ INTERFACE ] 2055 * pmap_enter: [ INTERFACE ]
2045 * 2056 *
2046 * Insert the given physical page (p) at 2057 * Insert the given physical page (p) at
2047 * the specified virtual address (v) in the 2058 * the specified virtual address (v) in the
2048 * target physical map with the protection requested. 2059 * target physical map with the protection requested.
2049 * 2060 *
2050 * If specified, the page will be wired down, meaning 2061 * If specified, the page will be wired down, meaning
2051 * that the related pte can not be reclaimed. 2062 * that the related pte can not be reclaimed.
2052 * 2063 *
2053 * Note: This is the only routine which MAY NOT lazy-evaluate 2064 * Note: This is the only routine which MAY NOT lazy-evaluate
2054 * or lose information. That is, this routine must actually 2065 * or lose information. That is, this routine must actually
2055 * insert this page into the given map NOW. 2066 * insert this page into the given map NOW.
2056 */ 2067 */
2057int 2068int
2058pmap_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags) 2069pmap_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags)
2059{ 2070{
2060 pt_entry_t *pte, npte, opte; 2071 pt_entry_t *pte, npte, opte;
2061 pv_entry_t opv = NULL; 2072 pv_entry_t opv = NULL;
2062 paddr_t opa; 2073 paddr_t opa;
2063 bool tflush = false; 2074 bool tflush = false;
2064 int error = 0; 2075 int error = 0;
2065 kmutex_t *lock; 2076 kmutex_t *lock;
2066 2077
2067#ifdef DEBUG 2078#ifdef DEBUG
2068 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER)) 2079 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER))
2069 printf("pmap_enter(%p, %lx, %lx, %x, %x)\n", 2080 printf("pmap_enter(%p, %lx, %lx, %x, %x)\n",
2070 pmap, va, pa, prot, flags); 2081 pmap, va, pa, prot, flags);
2071#endif 2082#endif
2072 struct vm_page * const pg = PHYS_TO_VM_PAGE(pa); 2083 struct vm_page * const pg = PHYS_TO_VM_PAGE(pa);
2073 const bool wired = (flags & PMAP_WIRED) != 0; 2084 const bool wired = (flags & PMAP_WIRED) != 0;
2074 2085
2075 PMAP_MAP_TO_HEAD_LOCK(); 2086 PMAP_MAP_TO_HEAD_LOCK();
2076 PMAP_LOCK(pmap); 2087 PMAP_LOCK(pmap);
2077 2088
2078 if (pmap == pmap_kernel()) { 2089 if (pmap == pmap_kernel()) {
2079 KASSERT(va >= VM_MIN_KERNEL_ADDRESS); 2090 KASSERT(va >= VM_MIN_KERNEL_ADDRESS);
2080 pte = PMAP_KERNEL_PTE(va); 2091 pte = PMAP_KERNEL_PTE(va);
2081 } else { 2092 } else {
2082 pt_entry_t *l1pte, *l2pte; 2093 pt_entry_t *l1pte, *l2pte;
2083 pt_entry_t * const lev1map = pmap_lev1map(pmap); 2094 pt_entry_t * const lev1map = pmap_lev1map(pmap);
2084 2095
2085 KASSERT(va < VM_MAXUSER_ADDRESS); 2096 KASSERT(va < VM_MAXUSER_ADDRESS);
2086 KASSERT(lev1map != kernel_lev1map); 2097 KASSERT(lev1map != kernel_lev1map);
2087 2098
2088 /* 2099 /*
2089 * Check to see if the level 1 PTE is valid, and 2100 * Check to see if the level 1 PTE is valid, and
2090 * allocate a new level 2 page table page if it's not. 2101 * allocate a new level 2 page table page if it's not.
2091 * A reference will be added to the level 2 table when 2102 * A reference will be added to the level 2 table when
2092 * the level 3 table is created. 2103 * the level 3 table is created.
2093 */ 2104 */
2094 l1pte = pmap_l1pte(lev1map, va); 2105 l1pte = pmap_l1pte(lev1map, va);
2095 if (pmap_pte_v(l1pte) == 0) { 2106 if (pmap_pte_v(l1pte) == 0) {
2096 pmap_physpage_addref(l1pte); 2107 pmap_physpage_addref(l1pte);
2097 error = pmap_ptpage_alloc(l1pte, PGU_L2PT); 2108 error = pmap_ptpage_alloc(l1pte, PGU_L2PT);
2098 if (error) { 2109 if (error) {
2099 pmap_l1pt_delref(pmap, l1pte); 2110 pmap_l1pt_delref(pmap, l1pte);
2100 if (flags & PMAP_CANFAIL) 2111 if (flags & PMAP_CANFAIL)
2101 goto out; 2112 goto out;
2102 panic("pmap_enter: unable to create L2 PT " 2113 panic("pmap_enter: unable to create L2 PT "
2103 "page"); 2114 "page");
2104 } 2115 }
2105#ifdef DEBUG 2116#ifdef DEBUG
2106 if (pmapdebug & PDB_PTPAGE) 2117 if (pmapdebug & PDB_PTPAGE)
2107 printf("pmap_enter: new level 2 table at " 2118 printf("pmap_enter: new level 2 table at "
2108 "0x%lx\n", pmap_pte_pa(l1pte)); 2119 "0x%lx\n", pmap_pte_pa(l1pte));
2109#endif 2120#endif
2110 } 2121 }
2111 2122
2112 /* 2123 /*
2113 * Check to see if the level 2 PTE is valid, and 2124 * Check to see if the level 2 PTE is valid, and
2114 * allocate a new level 3 page table page if it's not. 2125 * allocate a new level 3 page table page if it's not.
2115 * A reference will be added to the level 3 table when 2126 * A reference will be added to the level 3 table when
2116 * the mapping is validated. 2127 * the mapping is validated.
2117 */ 2128 */
2118 l2pte = pmap_l2pte(lev1map, va, l1pte); 2129 l2pte = pmap_l2pte(lev1map, va, l1pte);
2119 if (pmap_pte_v(l2pte) == 0) { 2130 if (pmap_pte_v(l2pte) == 0) {
2120 pmap_physpage_addref(l2pte); 2131 pmap_physpage_addref(l2pte);
2121 error = pmap_ptpage_alloc(l2pte, PGU_L3PT); 2132 error = pmap_ptpage_alloc(l2pte, PGU_L3PT);
2122 if (error) { 2133 if (error) {
2123 /* unlocks pmap */ 2134 /* unlocks pmap */
2124 pmap_enter_l2pt_delref(pmap, l1pte, l2pte); 2135 pmap_enter_l2pt_delref(pmap, l1pte, l2pte);
2125 if (flags & PMAP_CANFAIL) { 2136 if (flags & PMAP_CANFAIL) {
2126 PMAP_LOCK(pmap); 2137 PMAP_LOCK(pmap);
2127 goto out; 2138 goto out;
2128 } 2139 }
2129 panic("pmap_enter: unable to create L3 PT " 2140 panic("pmap_enter: unable to create L3 PT "
2130 "page"); 2141 "page");
2131 } 2142 }
2132#ifdef DEBUG 2143#ifdef DEBUG
2133 if (pmapdebug & PDB_PTPAGE) 2144 if (pmapdebug & PDB_PTPAGE)
2134 printf("pmap_enter: new level 3 table at " 2145 printf("pmap_enter: new level 3 table at "
2135 "0x%lx\n", pmap_pte_pa(l2pte)); 2146 "0x%lx\n", pmap_pte_pa(l2pte));
2136#endif 2147#endif
2137 } 2148 }
2138 2149
2139 /* 2150 /*
2140 * Get the PTE that will map the page. 2151 * Get the PTE that will map the page.
2141 */ 2152 */
2142 pte = pmap_l3pte(lev1map, va, l2pte); 2153 pte = pmap_l3pte(lev1map, va, l2pte);
2143 } 2154 }
2144 2155
2145 /* Remember all of the old PTE; used for TBI check later. */ 2156 /* Remember all of the old PTE; used for TBI check later. */
2146 opte = atomic_load_relaxed(pte); 2157 opte = atomic_load_relaxed(pte);
2147 2158
2148 /* 2159 /*
2149 * Check to see if the old mapping is valid. If not, validate the 2160 * Check to see if the old mapping is valid. If not, validate the
2150 * new one immediately. 2161 * new one immediately.
2151 */ 2162 */
2152 if ((opte & PG_V) == 0) { 2163 if ((opte & PG_V) == 0) {
2153 /* No TLB invalidatons needed for new mappings. */ 2164 /* No TLB invalidatons needed for new mappings. */
2154 2165
2155 if (pmap != pmap_kernel()) { 2166 if (pmap != pmap_kernel()) {
2156 /* 2167 /*
2157 * New mappings gain a reference on the level 3 2168 * New mappings gain a reference on the level 3
2158 * table. 2169 * table.
2159 */ 2170 */
2160 pmap_physpage_addref(pte); 2171 pmap_physpage_addref(pte);
2161 } 2172 }
2162 goto validate_enterpv; 2173 goto validate_enterpv;
2163 } 2174 }
2164 2175
2165 opa = pmap_pte_pa(pte); 2176 opa = pmap_pte_pa(pte);
2166 2177
2167 if (opa == pa) { 2178 if (opa == pa) {
2168 /* 2179 /*
2169 * Mapping has not changed; must be a protection or 2180 * Mapping has not changed; must be a protection or
2170 * wiring change. 2181 * wiring change.
2171 */ 2182 */
2172 if (pmap_pte_w_chg(pte, wired ? PG_WIRED : 0)) { 2183 if (pmap_pte_w_chg(pte, wired ? PG_WIRED : 0)) {
2173#ifdef DEBUG 2184#ifdef DEBUG
2174 if (pmapdebug & PDB_ENTER) 2185 if (pmapdebug & PDB_ENTER)
2175 printf("pmap_enter: wiring change -> %d\n", 2186 printf("pmap_enter: wiring change -> %d\n",
2176 wired); 2187 wired);
2177#endif 2188#endif
2178 /* Adjust the wiring count. */ 2189 /* Adjust the wiring count. */
2179 if (wired) 2190 if (wired)
2180 PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1); 2191 PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1);
2181 else 2192 else
2182 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1); 2193 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1);
2183 } 2194 }
2184 2195
2185 /* Set the PTE. */ 2196 /* Set the PTE. */
2186 goto validate; 2197 goto validate;
2187 } 2198 }
2188 2199
2189 /* 2200 /*
2190 * The mapping has changed. We need to invalidate the 2201 * The mapping has changed. We need to invalidate the
2191 * old mapping before creating the new one. 2202 * old mapping before creating the new one.
2192 */ 2203 */
2193#ifdef DEBUG 2204#ifdef DEBUG
2194 if (pmapdebug & PDB_ENTER) 2205 if (pmapdebug & PDB_ENTER)
2195 printf("pmap_enter: removing old mapping 0x%lx\n", va); 2206 printf("pmap_enter: removing old mapping 0x%lx\n", va);
2196#endif 2207#endif
2197 if (pmap != pmap_kernel()) { 2208 if (pmap != pmap_kernel()) {
2198 /* 2209 /*
2199 * Gain an extra reference on the level 3 table. 2210 * Gain an extra reference on the level 3 table.
2200 * pmap_remove_mapping() will delete a reference, 2211 * pmap_remove_mapping() will delete a reference,
2201 * and we don't want the table to be erroneously 2212 * and we don't want the table to be erroneously
2202 * freed. 2213 * freed.
2203 */ 2214 */
2204 pmap_physpage_addref(pte); 2215 pmap_physpage_addref(pte);
2205 } 2216 }
2206 /* Already have the bits from opte above. */ 2217 /* Already have the bits from opte above. */
2207 (void) pmap_remove_mapping(pmap, va, pte, true, &opv, NULL); 2218 (void) pmap_remove_mapping(pmap, va, pte, true, &opv, NULL);
2208 2219
2209 validate_enterpv: 2220 validate_enterpv:
2210 /* Enter the mapping into the pv_table if appropriate. */ 2221 /* Enter the mapping into the pv_table if appropriate. */
2211 if (pg != NULL) { 2222 if (pg != NULL) {
2212 error = pmap_pv_enter(pmap, pg, va, pte, true, opv); 2223 error = pmap_pv_enter(pmap, pg, va, pte, true, opv);
2213 if (error) { 2224 if (error) {
2214 /* This can only fail if opv == NULL */ 2225 /* This can only fail if opv == NULL */
2215 KASSERT(opv == NULL); 2226 KASSERT(opv == NULL);
2216 2227
2217 /* unlocks pmap */ 2228 /* unlocks pmap */
2218 pmap_enter_l3pt_delref(pmap, va, pte); 2229 pmap_enter_l3pt_delref(pmap, va, pte);
2219 if (flags & PMAP_CANFAIL) { 2230 if (flags & PMAP_CANFAIL) {
2220 PMAP_LOCK(pmap); 2231 PMAP_LOCK(pmap);
2221 goto out; 2232 goto out;
2222 } 2233 }
2223 panic("pmap_enter: unable to enter mapping in PV " 2234 panic("pmap_enter: unable to enter mapping in PV "
2224 "table"); 2235 "table");
2225 } 2236 }
2226 opv = NULL; 2237 opv = NULL;
2227 } 2238 }
2228 2239
2229 /* Increment counters. */ 2240 /* Increment counters. */
2230 PMAP_STAT_INCR(pmap->pm_stats.resident_count, 1); 2241 PMAP_STAT_INCR(pmap->pm_stats.resident_count, 1);
2231 if (wired) 2242 if (wired)
2232 PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1); 2243 PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1);
2233 2244
2234 validate: 2245 validate:
2235 /* Build the new PTE. */ 2246 /* Build the new PTE. */
2236 npte = ((pa >> PGSHIFT) << PG_SHIFT) | pte_prot(pmap, prot) | PG_V; 2247 npte = ((pa >> PGSHIFT) << PG_SHIFT) | pte_prot(pmap, prot) | PG_V;
2237 if (pg != NULL) { 2248 if (pg != NULL) {
2238 struct vm_page_md * const md = VM_PAGE_TO_MD(pg); 2249 struct vm_page_md * const md = VM_PAGE_TO_MD(pg);
2239 int attrs; 2250 int attrs;
2240 2251
2241 KASSERT(((flags & VM_PROT_ALL) & ~prot) == 0); 2252 KASSERT(((flags & VM_PROT_ALL) & ~prot) == 0);
2242 2253
2243 lock = pmap_pvh_lock(pg); 2254 lock = pmap_pvh_lock(pg);
2244 mutex_enter(lock); 2255 mutex_enter(lock);
2245 if (flags & VM_PROT_WRITE) 2256 if (flags & VM_PROT_WRITE)
2246 md->pvh_attrs |= (PGA_REFERENCED|PGA_MODIFIED); 2257 md->pvh_attrs |= (PGA_REFERENCED|PGA_MODIFIED);
2247 else if (flags & VM_PROT_ALL) 2258 else if (flags & VM_PROT_ALL)
2248 md->pvh_attrs |= PGA_REFERENCED; 2259 md->pvh_attrs |= PGA_REFERENCED;
2249 attrs = md->pvh_attrs; 2260 attrs = md->pvh_attrs;
2250 mutex_exit(lock); 2261 mutex_exit(lock);
2251 2262
2252 /* Set up referenced/modified emulation for new mapping. */ 2263 /* Set up referenced/modified emulation for new mapping. */
2253 if ((attrs & PGA_REFERENCED) == 0) 2264 if ((attrs & PGA_REFERENCED) == 0)
2254 npte |= PG_FOR | PG_FOW | PG_FOE; 2265 npte |= PG_FOR | PG_FOW | PG_FOE;
2255 else if ((attrs & PGA_MODIFIED) == 0) 2266 else if ((attrs & PGA_MODIFIED) == 0)
2256 npte |= PG_FOW; 2267 npte |= PG_FOW;
2257 2268
2258 /* 2269 /*
2259 * Mapping was entered on PV list. 2270 * Mapping was entered on PV list.
2260 */ 2271 */
2261 npte |= PG_PVLIST; 2272 npte |= PG_PVLIST;
2262 } 2273 }
2263 if (wired) 2274 if (wired)
2264 npte |= PG_WIRED; 2275 npte |= PG_WIRED;
2265#ifdef DEBUG 2276#ifdef DEBUG
2266 if (pmapdebug & PDB_ENTER) 2277 if (pmapdebug & PDB_ENTER)
2267 printf("pmap_enter: new pte = 0x%lx\n", npte); 2278 printf("pmap_enter: new pte = 0x%lx\n", npte);
2268#endif 2279#endif
2269 2280
2270 /* 2281 /*
2271 * If the HW / PALcode portion of the new PTE is the same as the 2282 * If the HW / PALcode portion of the new PTE is the same as the
2272 * old PTE, no TBI is necessary. 2283 * old PTE, no TBI is necessary.
2273 */ 2284 */
2274 if (opte & PG_V) { 2285 if (opte & PG_V) {
2275 tflush = PG_PALCODE(opte) != PG_PALCODE(npte); 2286 tflush = PG_PALCODE(opte) != PG_PALCODE(npte);
2276 } 2287 }
2277 2288
2278 /* Set the new PTE. */ 2289 /* Set the new PTE. */
2279 atomic_store_relaxed(pte, npte); 2290 atomic_store_relaxed(pte, npte);
2280 2291
2281out: 2292out:
2282 PMAP_MAP_TO_HEAD_UNLOCK(); 2293 PMAP_MAP_TO_HEAD_UNLOCK();
2283 2294
2284 /* 2295 /*
2285 * Invalidate the TLB entry for this VA and any appropriate 2296 * Invalidate the TLB entry for this VA and any appropriate
2286 * caches. 2297 * caches.
2287 */ 2298 */
2288 if (tflush) { 2299 if (tflush) {
2289 /* unlocks pmap */ 2300 /* unlocks pmap */
2290 pmap_enter_tlb_shootdown(pmap, va, opte, true); 2301 pmap_enter_tlb_shootdown(pmap, va, opte, true);
2291 if (pmap == pmap_kernel()) { 2302 if (pmap == pmap_kernel()) {
2292 TLB_COUNT(reason_enter_kernel); 2303 TLB_COUNT(reason_enter_kernel);
2293 } else { 2304 } else {
2294 TLB_COUNT(reason_enter_user); 2305 TLB_COUNT(reason_enter_user);
2295 } 2306 }
2296 } else { 2307 } else {
2297 PMAP_UNLOCK(pmap); 2308 PMAP_UNLOCK(pmap);
2298 } 2309 }
2299 2310
2300 if (opv) 2311 if (opv)
2301 pmap_pv_free(opv); 2312 pmap_pv_free(opv);
2302 2313
2303 return error; 2314 return error;
2304} 2315}
2305 2316
2306/* 2317/*
2307 * pmap_kenter_pa: [ INTERFACE ] 2318 * pmap_kenter_pa: [ INTERFACE ]
2308 * 2319 *
2309 * Enter a va -> pa mapping into the kernel pmap without any 2320 * Enter a va -> pa mapping into the kernel pmap without any
2310 * physical->virtual tracking. 2321 * physical->virtual tracking.
2311 * 2322 *
2312 * Note: no locking is necessary in this function. 2323 * Note: no locking is necessary in this function.
2313 */ 2324 */
2314void 2325void
2315pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags) 2326pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags)
2316{ 2327{
2317 pmap_t const pmap = pmap_kernel(); 2328 pmap_t const pmap = pmap_kernel();
2318 2329
2319#ifdef DEBUG 2330#ifdef DEBUG
2320 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER)) 2331 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER))
2321 printf("pmap_kenter_pa(%lx, %lx, %x)\n", 2332 printf("pmap_kenter_pa(%lx, %lx, %x)\n",
2322 va, pa, prot); 2333 va, pa, prot);
2323#endif 2334#endif
2324 2335
2325 KASSERT(va >= VM_MIN_KERNEL_ADDRESS); 2336 KASSERT(va >= VM_MIN_KERNEL_ADDRESS);
2326 2337
2327 pt_entry_t * const pte = PMAP_KERNEL_PTE(va); 2338 pt_entry_t * const pte = PMAP_KERNEL_PTE(va);
2328 2339
2329 /* Build the new PTE. */ 2340 /* Build the new PTE. */
2330 const pt_entry_t npte = 2341 const pt_entry_t npte =
2331 ((pa >> PGSHIFT) << PG_SHIFT) | pte_prot(pmap_kernel(), prot) | 2342 ((pa >> PGSHIFT) << PG_SHIFT) | pte_prot(pmap_kernel(), prot) |
2332 PG_V | PG_WIRED; 2343 PG_V | PG_WIRED;
2333 2344
2334 /* Set the new PTE. */ 2345 /* Set the new PTE. */
2335 const pt_entry_t opte = atomic_load_relaxed(pte); 2346 const pt_entry_t opte = atomic_load_relaxed(pte);
2336 atomic_store_relaxed(pte, npte); 2347 atomic_store_relaxed(pte, npte);
2337 2348
2338 PMAP_STAT_INCR(pmap->pm_stats.resident_count, 1); 2349 PMAP_STAT_INCR(pmap->pm_stats.resident_count, 1);
2339 PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1); 2350 PMAP_STAT_INCR(pmap->pm_stats.wired_count, 1);
2340 2351
2341 /* 2352 /*
2342 * There should not have been anything here, previously, 2353 * There should not have been anything here, previously,
2343 * so we can skip TLB shootdowns, etc. in the common case. 2354 * so we can skip TLB shootdowns, etc. in the common case.
2344 */ 2355 */
2345 if (__predict_false(opte & PG_V)) { 2356 if (__predict_false(opte & PG_V)) {
2346 const pt_entry_t diff = npte ^ opte; 2357 const pt_entry_t diff = npte ^ opte;
2347 2358
2348 printf_nolog("%s: mapping already present\n", __func__); 2359 printf_nolog("%s: mapping already present\n", __func__);
2349 PMAP_STAT_DECR(pmap->pm_stats.resident_count, 1); 2360 PMAP_STAT_DECR(pmap->pm_stats.resident_count, 1);
2350 if (diff & PG_WIRED) 2361 if (diff & PG_WIRED)
2351 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1); 2362 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1);
2352 /* XXX Can't handle this case. */ 2363 /* XXX Can't handle this case. */
2353 if (diff & PG_PVLIST) 2364 if (diff & PG_PVLIST)
2354 panic("pmap_kenter_pa: old mapping was managed"); 2365 panic("pmap_kenter_pa: old mapping was managed");
2355 2366
2356 pmap_enter_tlb_shootdown(pmap_kernel(), va, opte, false); 2367 pmap_enter_tlb_shootdown(pmap_kernel(), va, opte, false);
2357 TLB_COUNT(reason_kenter); 2368 TLB_COUNT(reason_kenter);
2358 } 2369 }
2359} 2370}
2360 2371
2361/* 2372/*
2362 * pmap_kremove: [ INTERFACE ] 2373 * pmap_kremove: [ INTERFACE ]
2363 * 2374 *
2364 * Remove a mapping entered with pmap_kenter_pa() starting at va, 2375 * Remove a mapping entered with pmap_kenter_pa() starting at va,
2365 * for size bytes (assumed to be page rounded). 2376 * for size bytes (assumed to be page rounded).
2366 */ 2377 */
2367void 2378void
2368pmap_kremove(vaddr_t va, vsize_t size) 2379pmap_kremove(vaddr_t va, vsize_t size)
2369{ 2380{
2370 pt_entry_t *pte, opte; 2381 pt_entry_t *pte, opte;
2371 pmap_t const pmap = pmap_kernel(); 2382 pmap_t const pmap = pmap_kernel();
2372 struct pmap_tlb_context tlbctx; 2383 struct pmap_tlb_context tlbctx;
2373 int count = 0; 2384 int count = 0;
2374 2385
2375#ifdef DEBUG 2386#ifdef DEBUG
2376 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER)) 2387 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER))
2377 printf("pmap_kremove(%lx, %lx)\n", 2388 printf("pmap_kremove(%lx, %lx)\n",
2378 va, size); 2389 va, size);
2379#endif 2390#endif
2380 2391
2381 pmap_tlb_context_init(&tlbctx, 0); 2392 pmap_tlb_context_init(&tlbctx, 0);
2382 2393
2383 KASSERT(va >= VM_MIN_KERNEL_ADDRESS); 2394 KASSERT(va >= VM_MIN_KERNEL_ADDRESS);
2384 2395
2385 for (; size != 0; size -= PAGE_SIZE, va += PAGE_SIZE) { 2396 for (; size != 0; size -= PAGE_SIZE, va += PAGE_SIZE) {
2386 pte = PMAP_KERNEL_PTE(va); 2397 pte = PMAP_KERNEL_PTE(va);
2387 opte = atomic_load_relaxed(pte); 2398 opte = atomic_load_relaxed(pte);
2388 if (opte & PG_V) { 2399 if (opte & PG_V) {
2389 KASSERT((opte & PG_PVLIST) == 0); 2400 KASSERT((opte & PG_PVLIST) == 0);
2390 2401
2391 /* Zap the mapping. */ 2402 /* Zap the mapping. */
2392 atomic_store_relaxed(pte, PG_NV); 2403 atomic_store_relaxed(pte, PG_NV);
2393 pmap_tlb_shootdown(pmap, va, opte, &tlbctx); 2404 pmap_tlb_shootdown(pmap, va, opte, &tlbctx);
2394 2405
2395 count++; 2406 count++;
2396 } 2407 }
2397 } 2408 }
2398 2409
2399 /* Update stats. */ 2410 /* Update stats. */
2400 if (__predict_true(count != 0)) { 2411 if (__predict_true(count != 0)) {
2401 PMAP_STAT_DECR(pmap->pm_stats.resident_count, count); 2412 PMAP_STAT_DECR(pmap->pm_stats.resident_count, count);
2402 PMAP_STAT_DECR(pmap->pm_stats.wired_count, count); 2413 PMAP_STAT_DECR(pmap->pm_stats.wired_count, count);
2403 } 2414 }
2404 2415
2405 pmap_tlb_shootnow(&tlbctx); 2416 pmap_tlb_shootnow(&tlbctx);
2406 TLB_COUNT(reason_kremove); 2417 TLB_COUNT(reason_kremove);
2407} 2418}
2408 2419
2409/* 2420/*
2410 * pmap_unwire: [ INTERFACE ] 2421 * pmap_unwire: [ INTERFACE ]
2411 * 2422 *
2412 * Clear the wired attribute for a map/virtual-address pair. 2423 * Clear the wired attribute for a map/virtual-address pair.
2413 * 2424 *
2414 * The mapping must already exist in the pmap. 2425 * The mapping must already exist in the pmap.
2415 */ 2426 */
2416void 2427void
2417pmap_unwire(pmap_t pmap, vaddr_t va) 2428pmap_unwire(pmap_t pmap, vaddr_t va)
2418{ 2429{
2419 pt_entry_t *pte; 2430 pt_entry_t *pte;
2420 2431
2421#ifdef DEBUG 2432#ifdef DEBUG
2422 if (pmapdebug & PDB_FOLLOW) 2433 if (pmapdebug & PDB_FOLLOW)
2423 printf("pmap_unwire(%p, %lx)\n", pmap, va); 2434 printf("pmap_unwire(%p, %lx)\n", pmap, va);
2424#endif 2435#endif
2425 2436
2426 PMAP_LOCK(pmap); 2437 PMAP_LOCK(pmap);
2427 2438
2428 pte = pmap_l3pte(pmap_lev1map(pmap), va, NULL); 2439 pte = pmap_l3pte(pmap_lev1map(pmap), va, NULL);
2429 2440
2430 KASSERT(pte != NULL); 2441 KASSERT(pte != NULL);
2431 KASSERT(pmap_pte_v(pte)); 2442 KASSERT(pmap_pte_v(pte));
2432 2443
2433 /* 2444 /*
2434 * If wiring actually changed (always?) clear the wire bit and 2445 * If wiring actually changed (always?) clear the wire bit and
2435 * update the wire count. Note that wiring is not a hardware 2446 * update the wire count. Note that wiring is not a hardware
2436 * characteristic so there is no need to invalidate the TLB. 2447 * characteristic so there is no need to invalidate the TLB.
2437 */ 2448 */
2438 if (pmap_pte_w_chg(pte, 0)) { 2449 if (pmap_pte_w_chg(pte, 0)) {
2439 pmap_pte_set_w(pte, false); 2450 pmap_pte_set_w(pte, false);
2440 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1); 2451 PMAP_STAT_DECR(pmap->pm_stats.wired_count, 1);
2441 } 2452 }
2442#ifdef DEBUG 2453#ifdef DEBUG
2443 else { 2454 else {
2444 printf("pmap_unwire: wiring for pmap %p va 0x%lx " 2455 printf("pmap_unwire: wiring for pmap %p va 0x%lx "
2445 "didn't change!\n", pmap, va); 2456 "didn't change!\n", pmap, va);
2446 } 2457 }
2447#endif 2458#endif
2448 2459
2449 PMAP_UNLOCK(pmap); 2460 PMAP_UNLOCK(pmap);
2450} 2461}
2451 2462
2452/* 2463/*
2453 * pmap_extract: [ INTERFACE ] 2464 * pmap_extract: [ INTERFACE ]
2454 * 2465 *
2455 * Extract the physical address associated with the given 2466 * Extract the physical address associated with the given
2456 * pmap/virtual address pair. 2467 * pmap/virtual address pair.
2457 */ 2468 */
2458bool 2469bool
2459pmap_extract(pmap_t pmap, vaddr_t va, paddr_t *pap) 2470pmap_extract(pmap_t pmap, vaddr_t va, paddr_t *pap)
2460{ 2471{
2461 pt_entry_t *l1pte, *l2pte, *l3pte; 2472 pt_entry_t *l1pte, *l2pte, *l3pte;
2462 paddr_t pa; 2473 paddr_t pa;
2463 2474
2464#ifdef DEBUG 2475#ifdef DEBUG
2465 if (pmapdebug & PDB_FOLLOW) 2476 if (pmapdebug & PDB_FOLLOW)
2466 printf("pmap_extract(%p, %lx) -> ", pmap, va); 2477 printf("pmap_extract(%p, %lx) -> ", pmap, va);
2467#endif 2478#endif
2468 2479
2469 /* 2480 /*
2470 * Take a faster path for the kernel pmap. Avoids locking, 2481 * Take a faster path for the kernel pmap. Avoids locking,
2471 * handles K0SEG. 2482 * handles K0SEG.
2472 */ 2483 */
2473 if (__predict_true(pmap == pmap_kernel())) { 2484 if (__predict_true(pmap == pmap_kernel())) {
2474 if (__predict_true(vtophys_internal(va, pap))) { 2485 if (__predict_true(vtophys_internal(va, pap))) {
2475#ifdef DEBUG 2486#ifdef DEBUG
2476 if (pmapdebug & PDB_FOLLOW) 2487 if (pmapdebug & PDB_FOLLOW)
2477 printf("0x%lx (kernel vtophys)\n", pa); 2488 printf("0x%lx (kernel vtophys)\n", pa);
2478#endif 2489#endif
2479 return true; 2490 return true;
2480 } 2491 }
2481#ifdef DEBUG 2492#ifdef DEBUG
2482 if (pmapdebug & PDB_FOLLOW) 2493 if (pmapdebug & PDB_FOLLOW)
2483 printf("failed (kernel vtophys)\n"); 2494 printf("failed (kernel vtophys)\n");
2484#endif 2495#endif
2485 return false; 2496 return false;
2486 } 2497 }
2487 2498
2488 pt_entry_t * const lev1map = pmap_lev1map(pmap); 2499 pt_entry_t * const lev1map = pmap_lev1map(pmap);
2489 2500
2490 PMAP_LOCK(pmap); 2501 PMAP_LOCK(pmap);
2491 2502
2492 l1pte = pmap_l1pte(lev1map, va); 2503 l1pte = pmap_l1pte(lev1map, va);
2493 if (pmap_pte_v(l1pte) == 0) 2504 if (pmap_pte_v(l1pte) == 0)
2494 goto out; 2505 goto out;
2495 2506
2496 l2pte = pmap_l2pte(lev1map, va, l1pte); 2507 l2pte = pmap_l2pte(lev1map, va, l1pte);
2497 if (pmap_pte_v(l2pte) == 0) 2508 if (pmap_pte_v(l2pte) == 0)
2498 goto out; 2509 goto out;
2499 2510
2500 l3pte = pmap_l3pte(lev1map, va, l2pte); 2511 l3pte = pmap_l3pte(lev1map, va, l2pte);
2501 if (pmap_pte_v(l3pte) == 0) 2512 if (pmap_pte_v(l3pte) == 0)
2502 goto out; 2513 goto out;
2503 2514
2504 pa = pmap_pte_pa(l3pte) | (va & PGOFSET); 2515 pa = pmap_pte_pa(l3pte) | (va & PGOFSET);
2505 PMAP_UNLOCK(pmap); 2516 PMAP_UNLOCK(pmap);
2506 if (pap != NULL) 2517 if (pap != NULL)
2507 *pap = pa; 2518 *pap = pa;
2508#ifdef DEBUG 2519#ifdef DEBUG
2509 if (pmapdebug & PDB_FOLLOW) 2520 if (pmapdebug & PDB_FOLLOW)
2510 printf("0x%lx\n", pa); 2521 printf("0x%lx\n", pa);
2511#endif 2522#endif
2512 return (true); 2523 return (true);
2513 2524
2514 out: 2525 out:
2515 PMAP_UNLOCK(pmap); 2526 PMAP_UNLOCK(pmap);
2516#ifdef DEBUG 2527#ifdef DEBUG
2517 if (pmapdebug & PDB_FOLLOW) 2528 if (pmapdebug & PDB_FOLLOW)
2518 printf("failed\n"); 2529 printf("failed\n");
2519#endif 2530#endif
2520 return (false); 2531 return (false);
2521} 2532}
2522 2533
2523/* 2534/*
2524 * pmap_copy: [ INTERFACE ] 2535 * pmap_copy: [ INTERFACE ]
2525 * 2536 *
2526 * Copy the mapping range specified by src_addr/len 2537 * Copy the mapping range specified by src_addr/len
2527 * from the source map to the range dst_addr/len 2538 * from the source map to the range dst_addr/len
2528 * in the destination map. 2539 * in the destination map.
2529 * 2540 *
2530 * This routine is only advisory and need not do anything. 2541 * This routine is only advisory and need not do anything.
2531 */ 2542 */
2532/* call deleted in <machine/pmap.h> */ 2543/* call deleted in <machine/pmap.h> */
2533 2544
2534/* 2545/*
2535 * pmap_update: [ INTERFACE ] 2546 * pmap_update: [ INTERFACE ]
2536 * 2547 *
2537 * Require that all active physical maps contain no 2548 * Require that all active physical maps contain no
2538 * incorrect entries NOW, by processing any deferred 2549 * incorrect entries NOW, by processing any deferred
2539 * pmap operations. 2550 * pmap operations.
2540 */ 2551 */
2541/* call deleted in <machine/pmap.h> */ 2552/* call deleted in <machine/pmap.h> */
2542 2553
2543/* 2554/*
2544 * pmap_activate: [ INTERFACE ] 2555 * pmap_activate: [ INTERFACE ]
2545 * 2556 *
2546 * Activate the pmap used by the specified process. This includes 2557 * Activate the pmap used by the specified process. This includes
2547 * reloading the MMU context of the current process, and marking 2558 * reloading the MMU context of the current process, and marking
2548 * the pmap in use by the processor. 2559 * the pmap in use by the processor.
2549 */ 2560 */
2550void 2561void
2551pmap_activate(struct lwp *l) 2562pmap_activate(struct lwp *l)
2552{ 2563{
2553 struct pmap * const pmap = l->l_proc->p_vmspace->vm_map.pmap; 2564 struct pmap * const pmap = l->l_proc->p_vmspace->vm_map.pmap;
2554 struct pcb * const pcb = lwp_getpcb(l); 2565 struct pcb * const pcb = lwp_getpcb(l);
2555 2566
2556#ifdef DEBUG 2567#ifdef DEBUG
2557 if (pmapdebug & PDB_FOLLOW) 2568 if (pmapdebug & PDB_FOLLOW)
2558 printf("pmap_activate(%p)\n", l); 2569 printf("pmap_activate(%p)\n", l);
2559#endif 2570#endif
2560 2571
2561 KASSERT(kpreempt_disabled()); 2572 KASSERT(kpreempt_disabled());
2562 2573
2563 struct cpu_info * const ci = curcpu(); 2574 struct cpu_info * const ci = curcpu();
2564 2575
2565 KASSERT(l == ci->ci_curlwp); 2576 KASSERT(l == ci->ci_curlwp);
2566 2577
2567 u_long const old_ptbr = pcb->pcb_hw.apcb_ptbr; 2578 u_long const old_ptbr = pcb->pcb_hw.apcb_ptbr;
2568 u_int const old_asn = pcb->pcb_hw.apcb_asn; 2579 u_int const old_asn = pcb->pcb_hw.apcb_asn;
2569 2580
2570 /* 2581 /*
2571 * We hold the activation lock to synchronize with TLB shootdown. 2582 * We hold the activation lock to synchronize with TLB shootdown.
2572 * The kernel pmap does not require those tests because shootdowns 2583 * The kernel pmap does not require those tests because shootdowns
2573 * for the kernel pmap are always sent to all CPUs. 2584 * for the kernel pmap are always sent to all CPUs.
2574 */ 2585 */
2575 if (pmap != pmap_kernel()) { 2586 if (pmap != pmap_kernel()) {
2576 PMAP_ACT_LOCK(pmap); 2587 PMAP_ACT_LOCK(pmap);
2577 pcb->pcb_hw.apcb_asn = pmap_asn_alloc(pmap, ci); 2588 pcb->pcb_hw.apcb_asn = pmap_asn_alloc(pmap, ci);
2578 atomic_or_ulong(&pmap->pm_cpus, (1UL << ci->ci_cpuid)); 2589 atomic_or_ulong(&pmap->pm_cpus, (1UL << ci->ci_cpuid));
2579 } else { 2590 } else {
2580 pcb->pcb_hw.apcb_asn = PMAP_ASN_KERNEL; 2591 pcb->pcb_hw.apcb_asn = PMAP_ASN_KERNEL;
2581 } 2592 }
2582 pcb->pcb_hw.apcb_ptbr = 2593 pcb->pcb_hw.apcb_ptbr =
2583 ALPHA_K0SEG_TO_PHYS((vaddr_t)pmap_lev1map(pmap)) >> PGSHIFT; 2594 ALPHA_K0SEG_TO_PHYS((vaddr_t)pmap_lev1map(pmap)) >> PGSHIFT;
2584 2595
2585 /* 2596 /*
2586 * Check to see if the ASN or page table base has changed; if 2597 * Check to see if the ASN or page table base has changed; if
2587 * so, switch to our own context again so that it will take 2598 * so, switch to our own context again so that it will take
2588 * effect. 2599 * effect.
2589 * 2600 *
2590 * We test ASN first because it's the most likely value to change. 2601 * We test ASN first because it's the most likely value to change.
2591 */ 2602 */
2592 if (old_asn != pcb->pcb_hw.apcb_asn || 2603 if (old_asn != pcb->pcb_hw.apcb_asn ||
2593 old_ptbr != pcb->pcb_hw.apcb_ptbr) { 2604 old_ptbr != pcb->pcb_hw.apcb_ptbr) {
2594 if (old_asn != pcb->pcb_hw.apcb_asn && 2605 if (old_asn != pcb->pcb_hw.apcb_asn &&
2595 old_ptbr != pcb->pcb_hw.apcb_ptbr) { 2606 old_ptbr != pcb->pcb_hw.apcb_ptbr) {
2596 TLB_COUNT(activate_both_change); 2607 TLB_COUNT(activate_both_change);
2597 } else if (old_asn != pcb->pcb_hw.apcb_asn) { 2608 } else if (old_asn != pcb->pcb_hw.apcb_asn) {
2598 TLB_COUNT(activate_asn_change); 2609 TLB_COUNT(activate_asn_change);
2599 } else { 2610 } else {
2600 TLB_COUNT(activate_ptbr_change); 2611 TLB_COUNT(activate_ptbr_change);
2601 } 2612 }
2602 (void) alpha_pal_swpctx((u_long)l->l_md.md_pcbpaddr); 2613 (void) alpha_pal_swpctx((u_long)l->l_md.md_pcbpaddr);
2603 TLB_COUNT(activate_swpctx); 2614 TLB_COUNT(activate_swpctx);
2604 } else { 2615 } else {
2605 TLB_COUNT(activate_skip_swpctx); 2616 TLB_COUNT(activate_skip_swpctx);
2606 } 2617 }
2607 2618
2608 pmap_reference(pmap); 2619 pmap_reference(pmap);
2609 ci->ci_pmap = pmap; 2620 ci->ci_pmap = pmap;
2610 2621
2611 if (pmap != pmap_kernel()) { 2622 if (pmap != pmap_kernel()) {
2612 PMAP_ACT_UNLOCK(pmap); 2623 PMAP_ACT_UNLOCK(pmap);
2613 } 2624 }
2614} 2625}
2615 2626
2616/* 2627/*
2617 * pmap_deactivate: [ INTERFACE ] 2628 * pmap_deactivate: [ INTERFACE ]
2618 * 2629 *
2619 * Mark that the pmap used by the specified process is no longer 2630 * Mark that the pmap used by the specified process is no longer
2620 * in use by the processor. 2631 * in use by the processor.
2621 */ 2632 */
2622void 2633void
2623pmap_deactivate(struct lwp *l) 2634pmap_deactivate(struct lwp *l)
2624{ 2635{
2625 struct pmap * const pmap = l->l_proc->p_vmspace->vm_map.pmap; 2636 struct pmap * const pmap = l->l_proc->p_vmspace->vm_map.pmap;
2626 2637
2627#ifdef DEBUG 2638#ifdef DEBUG
2628 if (pmapdebug & PDB_FOLLOW) 2639 if (pmapdebug & PDB_FOLLOW)
2629 printf("pmap_deactivate(%p)\n", l); 2640 printf("pmap_deactivate(%p)\n", l);
2630#endif 2641#endif
2631 2642
2632 KASSERT(kpreempt_disabled()); 2643 KASSERT(kpreempt_disabled());
2633 2644
2634 struct cpu_info * const ci = curcpu(); 2645 struct cpu_info * const ci = curcpu();
2635 2646
2636 KASSERT(l == ci->ci_curlwp); 2647 KASSERT(l == ci->ci_curlwp);
2637 KASSERT(pmap == ci->ci_pmap); 2648 KASSERT(pmap == ci->ci_pmap);
2638 2649
2639 /* 2650 /*
2640 * There is no need to switch to a different PTBR here, 2651 * There is no need to switch to a different PTBR here,
2641 * because a pmap_activate() or SWPCTX is guaranteed 2652 * because a pmap_activate() or SWPCTX is guaranteed
2642 * before whatever lev1map we're on now is invalidated 2653 * before whatever lev1map we're on now is invalidated
2643 * or before user space is accessed again. 2654 * or before user space is accessed again.
2644 * 2655 *
2645 * Because only kernel mappings will be accessed before the 2656 * Because only kernel mappings will be accessed before the
2646 * next pmap_activate() call, we consider our CPU to be on 2657 * next pmap_activate() call, we consider our CPU to be on
2647 * the kernel pmap. 2658 * the kernel pmap.
2648 */ 2659 */
2649 ci->ci_pmap = pmap_kernel(); 2660 ci->ci_pmap = pmap_kernel();
2650 KASSERT(atomic_load_relaxed(&pmap->pm_count) > 1); 2661 KASSERT(atomic_load_relaxed(&pmap->pm_count) > 1);
2651 pmap_destroy(pmap); 2662 pmap_destroy(pmap);
2652} 2663}
2653 2664
2654/* 2665/*
2655 * pmap_zero_page: [ INTERFACE ] 2666 * pmap_zero_page: [ INTERFACE ]
2656 * 2667 *
2657 * Zero the specified (machine independent) page by mapping the page 2668 * Zero the specified (machine independent) page by mapping the page
2658 * into virtual memory and clear its contents, one machine dependent 2669 * into virtual memory and clear its contents, one machine dependent
2659 * page at a time. 2670 * page at a time.
2660 * 2671 *
2661 * Note: no locking is necessary in this function. 2672 * Note: no locking is necessary in this function.
2662 */ 2673 */
2663void 2674void
2664pmap_zero_page(paddr_t phys) 2675pmap_zero_page(paddr_t phys)
2665{ 2676{
2666 u_long *p0, *p1, *pend; 2677 u_long *p0, *p1, *pend;
2667 2678
2668#ifdef DEBUG 2679#ifdef DEBUG
2669 if (pmapdebug & PDB_FOLLOW) 2680 if (pmapdebug & PDB_FOLLOW)
2670 printf("pmap_zero_page(%lx)\n", phys); 2681 printf("pmap_zero_page(%lx)\n", phys);
2671#endif 2682#endif
2672 2683
2673 p0 = (u_long *)ALPHA_PHYS_TO_K0SEG(phys); 2684 p0 = (u_long *)ALPHA_PHYS_TO_K0SEG(phys);
2674 p1 = NULL; 2685 p1 = NULL;
2675 pend = (u_long *)((u_long)p0 + PAGE_SIZE); 2686 pend = (u_long *)((u_long)p0 + PAGE_SIZE);
2676 2687
2677 /* 2688 /*
2678 * Unroll the loop a bit, doing 16 quadwords per iteration. 2689 * Unroll the loop a bit, doing 16 quadwords per iteration.
2679 * Do only 8 back-to-back stores, and alternate registers. 2690 * Do only 8 back-to-back stores, and alternate registers.
2680 */ 2691 */
2681 do { 2692 do {
2682 __asm volatile( 2693 __asm volatile(
2683 "# BEGIN loop body\n" 2694 "# BEGIN loop body\n"
2684 " addq %2, (8 * 8), %1 \n" 2695 " addq %2, (8 * 8), %1 \n"
2685 " stq $31, (0 * 8)(%0) \n" 2696 " stq $31, (0 * 8)(%0) \n"
2686 " stq $31, (1 * 8)(%0) \n" 2697 " stq $31, (1 * 8)(%0) \n"
2687 " stq $31, (2 * 8)(%0) \n" 2698 " stq $31, (2 * 8)(%0) \n"
2688 " stq $31, (3 * 8)(%0) \n" 2699 " stq $31, (3 * 8)(%0) \n"
2689 " stq $31, (4 * 8)(%0) \n" 2700 " stq $31, (4 * 8)(%0) \n"
2690 " stq $31, (5 * 8)(%0) \n" 2701 " stq $31, (5 * 8)(%0) \n"
2691 " stq $31, (6 * 8)(%0) \n" 2702 " stq $31, (6 * 8)(%0) \n"
2692 " stq $31, (7 * 8)(%0) \n" 2703 " stq $31, (7 * 8)(%0) \n"
2693 " \n" 2704 " \n"
2694 " addq %3, (8 * 8), %0 \n" 2705 " addq %3, (8 * 8), %0 \n"
2695 " stq $31, (0 * 8)(%1) \n" 2706 " stq $31, (0 * 8)(%1) \n"
2696 " stq $31, (1 * 8)(%1) \n" 2707 " stq $31, (1 * 8)(%1) \n"
2697 " stq $31, (2 * 8)(%1) \n" 2708 " stq $31, (2 * 8)(%1) \n"
2698 " stq $31, (3 * 8)(%1) \n" 2709 " stq $31, (3 * 8)(%1) \n"
2699 " stq $31, (4 * 8)(%1) \n" 2710 " stq $31, (4 * 8)(%1) \n"
2700 " stq $31, (5 * 8)(%1) \n" 2711 " stq $31, (5 * 8)(%1) \n"
2701 " stq $31, (6 * 8)(%1) \n" 2712 " stq $31, (6 * 8)(%1) \n"
2702 " stq $31, (7 * 8)(%1) \n" 2713 " stq $31, (7 * 8)(%1) \n"
2703 " # END loop body" 2714 " # END loop body"
2704 : "=r" (p0), "=r" (p1) 2715 : "=r" (p0), "=r" (p1)
2705 : "0" (p0), "1" (p1) 2716 : "0" (p0), "1" (p1)
2706 : "memory"); 2717 : "memory");
2707 } while (p0 < pend); 2718 } while (p0 < pend);
2708} 2719}
2709 2720
2710/* 2721/*
2711 * pmap_copy_page: [ INTERFACE ] 2722 * pmap_copy_page: [ INTERFACE ]
2712 * 2723 *
2713 * Copy the specified (machine independent) page by mapping the page 2724 * Copy the specified (machine independent) page by mapping the page
2714 * into virtual memory and using memcpy to copy the page, one machine 2725 * into virtual memory and using memcpy to copy the page, one machine
2715 * dependent page at a time. 2726 * dependent page at a time.
2716 * 2727 *
2717 * Note: no locking is necessary in this function. 2728 * Note: no locking is necessary in this function.
2718 */ 2729 */
2719void 2730void
2720pmap_copy_page(paddr_t src, paddr_t dst) 2731pmap_copy_page(paddr_t src, paddr_t dst)
2721{ 2732{
2722 const void *s; 2733 const void *s;

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

--- src/sys/arch/alpha/include/pmap.h 2021/05/29 23:27:22 1.88
+++ src/sys/arch/alpha/include/pmap.h 2021/05/30 00:34:27 1.89
@@ -1,372 +1,375 @@ @@ -1,372 +1,375 @@
1/* $NetBSD: pmap.h,v 1.88 2021/05/29 23:27:22 thorpej Exp $ */ 1/* $NetBSD: pmap.h,v 1.89 2021/05/30 00:34:27 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
 135LIST_HEAD(pmap_pagelist, vm_page);
 136
134struct pmap_percpu { 137struct pmap_percpu {
135 unsigned int pmc_asn; /* address space number */ 138 unsigned int pmc_asn; /* address space number */
136 unsigned int pmc_pad0; 139 unsigned int pmc_pad0;
137 unsigned long pmc_asngen; /* ASN generation number */ 140 unsigned long pmc_asngen; /* ASN generation number */
138 unsigned int pmc_needisync; /* CPU needes isync */ 141 unsigned int pmc_needisync; /* CPU needes isync */
139 unsigned int pmc_pad1; 142 unsigned int pmc_pad1;
140 pt_entry_t *pmc_lev1map; /* level 1 map */ 143 pt_entry_t *pmc_lev1map; /* level 1 map */
141 unsigned long pmc_padN[(COHERENCY_UNIT / 8) - 4]; 144 unsigned long pmc_padN[(COHERENCY_UNIT / 8) - 4];
142}; 145};
143 146
144struct pmap { /* pmaps are aligned to COHERENCY_UNIT boundaries */ 147struct pmap { /* pmaps are aligned to COHERENCY_UNIT boundaries */
145 /* pmaps are locked by hashed mutexes */ 148 /* pmaps are locked by hashed mutexes */
146 unsigned long pm_cpus; /* [ 0] CPUs using pmap */ 149 unsigned long pm_cpus; /* [ 0] CPUs using pmap */
147 struct pmap_statistics pm_stats; /* [ 8] statistics */ 150 struct pmap_statistics pm_stats; /* [ 8] statistics */
148 unsigned int pm_count; /* [24] reference count */ 151 unsigned int pm_count; /* [24] reference count */
149 unsigned int __pm_spare0; /* [28] spare field */ 152 unsigned int __pm_spare0; /* [28] spare field */
150 unsigned long __pm_spare1; /* [32] spare field */ 153 unsigned long __pm_spare1; /* [32] spare field */
151 unsigned long __pm_spare2; /* [40] spare field */ 154 unsigned long __pm_spare2; /* [40] spare field */
152 TAILQ_ENTRY(pmap) pm_list; /* [48] list of all pmaps */ 155 TAILQ_ENTRY(pmap) pm_list; /* [48] list of all pmaps */
153 /* -- COHERENCY_UNIT boundary -- */ 156 /* -- COHERENCY_UNIT boundary -- */
154 struct pmap_percpu pm_percpu[]; /* [64] per-CPU data */ 157 struct pmap_percpu pm_percpu[]; /* [64] per-CPU data */
155 /* variable length */ 158 /* variable length */
156}; 159};
157 160
158#define PMAP_SIZEOF(x) \ 161#define PMAP_SIZEOF(x) \
159 (ALIGN(offsetof(struct pmap, pm_percpu[(x)]))) 162 (ALIGN(offsetof(struct pmap, pm_percpu[(x)])))
160 163
161#define PMAP_ASN_KERNEL 0 /* kernel-reserved ASN */ 164#define PMAP_ASN_KERNEL 0 /* kernel-reserved ASN */
162#define PMAP_ASN_FIRST_USER 1 /* first user ASN */ 165#define PMAP_ASN_FIRST_USER 1 /* first user ASN */
163#define PMAP_ASNGEN_INVALID 0 /* reserved (invalid) ASN generation */ 166#define PMAP_ASNGEN_INVALID 0 /* reserved (invalid) ASN generation */
164#define PMAP_ASNGEN_INITIAL 1 /* first valid generatation */ 167#define PMAP_ASNGEN_INITIAL 1 /* first valid generatation */
165 168
166/* 169/*
167 * 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
168 * 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.
169 */ 172 */
170typedef struct pv_entry { 173typedef struct pv_entry {
171 struct pv_entry *pv_next; /* next pv_entry on list */ 174 struct pv_entry *pv_next; /* next pv_entry on list */
172 struct pmap *pv_pmap; /* pmap where mapping lies */ 175 struct pmap *pv_pmap; /* pmap where mapping lies */
173 vaddr_t pv_va; /* virtual address for mapping */ 176 vaddr_t pv_va; /* virtual address for mapping */
174 pt_entry_t *pv_pte; /* PTE that maps the VA */ 177 pt_entry_t *pv_pte; /* PTE that maps the VA */
175} *pv_entry_t; 178} *pv_entry_t;
176 179
177/* pvh_attrs */ 180/* pvh_attrs */
178#define PGA_MODIFIED 0x01 /* modified */ 181#define PGA_MODIFIED 0x01 /* modified */
179#define PGA_REFERENCED 0x02 /* referenced */ 182#define PGA_REFERENCED 0x02 /* referenced */
180 183
181/* pvh_usage */ 184/* pvh_usage */
182#define PGU_NORMAL 0 /* free or normal use */ 185#define PGU_NORMAL 0 /* free or normal use */
183#define PGU_PVENT 1 /* PV entries */ 186#define PGU_PVENT 1 /* PV entries */
184#define PGU_L1PT 2 /* level 1 page table */ 187#define PGU_L1PT 2 /* level 1 page table */
185#define PGU_L2PT 3 /* level 2 page table */ 188#define PGU_L2PT 3 /* level 2 page table */
186#define PGU_L3PT 4 /* level 3 page table */ 189#define PGU_L3PT 4 /* level 3 page table */
187 190
188#ifdef _KERNEL 191#ifdef _KERNEL
189 192
190#include <sys/atomic.h> 193#include <sys/atomic.h>
191 194
192struct cpu_info; 195struct cpu_info;
193struct trapframe; 196struct trapframe;
194 197
195void pmap_init_cpu(struct cpu_info *); 198void pmap_init_cpu(struct cpu_info *);
196#if defined(MULTIPROCESSOR) 199#if defined(MULTIPROCESSOR)
197void pmap_tlb_shootdown_ipi(struct cpu_info *, struct trapframe *); 200void pmap_tlb_shootdown_ipi(struct cpu_info *, struct trapframe *);
198#endif /* MULTIPROCESSOR */ 201#endif /* MULTIPROCESSOR */
199 202
200#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count) 203#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count)
201#define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count) 204#define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count)
202 205
203#define pmap_copy(dp, sp, da, l, sa) /* nothing */ 206#define pmap_copy(dp, sp, da, l, sa) /* nothing */
204#define pmap_update(pmap) /* nothing (yet) */ 207#define pmap_update(pmap) /* nothing (yet) */
205 208
206static __inline bool 209static __inline bool
207pmap_remove_all(struct pmap *pmap) 210pmap_remove_all(struct pmap *pmap)
208{ 211{
209 /* Nothing. */ 212 /* Nothing. */
210 return false; 213 return false;
211} 214}
212 215
213#define pmap_is_referenced(pg) \ 216#define pmap_is_referenced(pg) \
214 (((pg)->mdpage.pvh_attrs & PGA_REFERENCED) != 0) 217 (((pg)->mdpage.pvh_attrs & PGA_REFERENCED) != 0)
215#define pmap_is_modified(pg) \ 218#define pmap_is_modified(pg) \
216 (((pg)->mdpage.pvh_attrs & PGA_MODIFIED) != 0) 219 (((pg)->mdpage.pvh_attrs & PGA_MODIFIED) != 0)
217 220
218#define PMAP_STEAL_MEMORY /* enable pmap_steal_memory() */ 221#define PMAP_STEAL_MEMORY /* enable pmap_steal_memory() */
219#define PMAP_GROWKERNEL /* enable pmap_growkernel() */ 222#define PMAP_GROWKERNEL /* enable pmap_growkernel() */
220 223
221#define PMAP_DIRECT 224#define PMAP_DIRECT
222#define PMAP_DIRECT_MAP(pa) ALPHA_PHYS_TO_K0SEG((pa)) 225#define PMAP_DIRECT_MAP(pa) ALPHA_PHYS_TO_K0SEG((pa))
223#define PMAP_DIRECT_UNMAP(va) ALPHA_K0SEG_TO_PHYS((va)) 226#define PMAP_DIRECT_UNMAP(va) ALPHA_K0SEG_TO_PHYS((va))
224 227
225static __inline int 228static __inline int
226pmap_direct_process(paddr_t pa, voff_t pgoff, size_t len, 229pmap_direct_process(paddr_t pa, voff_t pgoff, size_t len,
227 int (*process)(void *, size_t, void *), void *arg) 230 int (*process)(void *, size_t, void *), void *arg)
228{ 231{
229 vaddr_t va = PMAP_DIRECT_MAP(pa); 232 vaddr_t va = PMAP_DIRECT_MAP(pa);
230 233
231 return process((void *)(va + pgoff), len, arg); 234 return process((void *)(va + pgoff), len, arg);
232} 235}
233 236
234/* 237/*
235 * Alternate mapping hooks for pool pages. Avoids thrashing the TLB. 238 * Alternate mapping hooks for pool pages. Avoids thrashing the TLB.
236 */ 239 */
237#define PMAP_MAP_POOLPAGE(pa) PMAP_DIRECT_MAP(pa) 240#define PMAP_MAP_POOLPAGE(pa) PMAP_DIRECT_MAP(pa)
238#define PMAP_UNMAP_POOLPAGE(va) PMAP_DIRECT_UNMAP(va) 241#define PMAP_UNMAP_POOLPAGE(va) PMAP_DIRECT_UNMAP(va)
239 242
240/* 243/*
241 * Other hooks for the pool allocator. 244 * Other hooks for the pool allocator.
242 */ 245 */
243#define POOL_VTOPHYS(va) ALPHA_K0SEG_TO_PHYS((vaddr_t) (va)) 246#define POOL_VTOPHYS(va) ALPHA_K0SEG_TO_PHYS((vaddr_t) (va))
244 247
245bool pmap_pageidlezero(paddr_t); 248bool pmap_pageidlezero(paddr_t);
246#define PMAP_PAGEIDLEZERO(pa) pmap_pageidlezero((pa)) 249#define PMAP_PAGEIDLEZERO(pa) pmap_pageidlezero((pa))
247 250
248paddr_t vtophys(vaddr_t); 251paddr_t vtophys(vaddr_t);
249 252
250/* Machine-specific functions. */ 253/* Machine-specific functions. */
251void pmap_bootstrap(paddr_t, u_int, u_long); 254void pmap_bootstrap(paddr_t, u_int, u_long);
252int pmap_emulate_reference(struct lwp *, vaddr_t, int, int); 255int pmap_emulate_reference(struct lwp *, vaddr_t, int, int);
253 256
254#define pmap_pte_pa(pte) (PG_PFNUM(*(pte)) << PGSHIFT) 257#define pmap_pte_pa(pte) (PG_PFNUM(*(pte)) << PGSHIFT)
255#define pmap_pte_prot(pte) (*(pte) & PG_PROT) 258#define pmap_pte_prot(pte) (*(pte) & PG_PROT)
256#define pmap_pte_w(pte) (*(pte) & PG_WIRED) 259#define pmap_pte_w(pte) (*(pte) & PG_WIRED)
257#define pmap_pte_v(pte) (*(pte) & PG_V) 260#define pmap_pte_v(pte) (*(pte) & PG_V)
258#define pmap_pte_pv(pte) (*(pte) & PG_PVLIST) 261#define pmap_pte_pv(pte) (*(pte) & PG_PVLIST)
259#define pmap_pte_asm(pte) (*(pte) & PG_ASM) 262#define pmap_pte_asm(pte) (*(pte) & PG_ASM)
260#define pmap_pte_exec(pte) (*(pte) & PG_EXEC) 263#define pmap_pte_exec(pte) (*(pte) & PG_EXEC)
261 264
262#define pmap_pte_set_w(pte, v) \ 265#define pmap_pte_set_w(pte, v) \
263do { \ 266do { \
264 if (v) \ 267 if (v) \
265 *(pte) |= PG_WIRED; \ 268 *(pte) |= PG_WIRED; \
266 else \ 269 else \
267 *(pte) &= ~PG_WIRED; \ 270 *(pte) &= ~PG_WIRED; \
268} while (0) 271} while (0)
269 272
270#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))
271 274
272#define pmap_pte_set_prot(pte, np) \ 275#define pmap_pte_set_prot(pte, np) \
273do { \ 276do { \
274 *(pte) &= ~PG_PROT; \ 277 *(pte) &= ~PG_PROT; \
275 *(pte) |= (np); \ 278 *(pte) |= (np); \
276} while (0) 279} while (0)
277 280
278#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))
279 282
280static __inline pt_entry_t * 283static __inline pt_entry_t *
281pmap_lev1map(pmap_t pmap) 284pmap_lev1map(pmap_t pmap)
282{ 285{
283 if (__predict_false(pmap == pmap_kernel())) { 286 if (__predict_false(pmap == pmap_kernel())) {
284 return kernel_lev1map; 287 return kernel_lev1map;
285 } 288 }
286 /* 289 /*
287 * 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
288 * all CPUs, so don't bother disabling preemption around 291 * all CPUs, so don't bother disabling preemption around
289 * this. 292 * this.
290 */ 293 */
291 return pmap->pm_percpu[cpu_number()].pmc_lev1map; 294 return pmap->pm_percpu[cpu_number()].pmc_lev1map;
292} 295}
293 296
294static __inline pt_entry_t * 297static __inline pt_entry_t *
295pmap_l1pte(pt_entry_t *lev1map, vaddr_t v) 298pmap_l1pte(pt_entry_t *lev1map, vaddr_t v)
296{ 299{
297 KASSERT(lev1map != NULL); 300 KASSERT(lev1map != NULL);
298 return &lev1map[l1pte_index(v)]; 301 return &lev1map[l1pte_index(v)];
299} 302}
300 303
301static __inline pt_entry_t * 304static __inline pt_entry_t *
302pmap_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)
303{ 306{
304 pt_entry_t *lev2map; 307 pt_entry_t *lev2map;
305 308
306 if (l1pte == NULL) { 309 if (l1pte == NULL) {
307 l1pte = pmap_l1pte(lev1map, v); 310 l1pte = pmap_l1pte(lev1map, v);
308 if (pmap_pte_v(l1pte) == 0) 311 if (pmap_pte_v(l1pte) == 0)
309 return NULL; 312 return NULL;
310 } 313 }
311 314
312 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));
313 return &lev2map[l2pte_index(v)]; 316 return &lev2map[l2pte_index(v)];
314} 317}
315 318
316static __inline pt_entry_t * 319static __inline pt_entry_t *
317pmap_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)
318{ 321{
319 pt_entry_t *l1pte, *lev2map, *lev3map; 322 pt_entry_t *l1pte, *lev2map, *lev3map;
320 323
321 if (l2pte == NULL) { 324 if (l2pte == NULL) {
322 l1pte = pmap_l1pte(lev1map, v); 325 l1pte = pmap_l1pte(lev1map, v);
323 if (pmap_pte_v(l1pte) == 0) 326 if (pmap_pte_v(l1pte) == 0)
324 return NULL; 327 return NULL;
325 328
326 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));
327 l2pte = &lev2map[l2pte_index(v)]; 330 l2pte = &lev2map[l2pte_index(v)];
328 if (pmap_pte_v(l2pte) == 0) 331 if (pmap_pte_v(l2pte) == 0)
329 return NULL; 332 return NULL;
330 } 333 }
331 334
332 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));
333 return &lev3map[l3pte_index(v)]; 336 return &lev3map[l3pte_index(v)];
334} 337}
335 338
336/* 339/*
337 * Macro for processing deferred I-stream synchronization. 340 * Macro for processing deferred I-stream synchronization.
338 * 341 *
339 * 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
340 * return to userspace, since the IMB PALcode op can be quite 343 * return to userspace, since the IMB PALcode op can be quite
341 * expensive. Since user instructions won't be executed until 344 * expensive. Since user instructions won't be executed until
342 * the return to userspace, this can be deferred until userret(). 345 * the return to userspace, this can be deferred until userret().
343 */ 346 */
344#define PMAP_USERRET(pmap) \ 347#define PMAP_USERRET(pmap) \
345do { \ 348do { \
346 const unsigned long cpu_id = cpu_number(); \ 349 const unsigned long cpu_id = cpu_number(); \
347 \ 350 \
348 if ((pmap)->pm_percpu[cpu_id].pmc_needisync) { \ 351 if ((pmap)->pm_percpu[cpu_id].pmc_needisync) { \
349 (pmap)->pm_percpu[cpu_id].pmc_needisync = 0; \ 352 (pmap)->pm_percpu[cpu_id].pmc_needisync = 0; \
350 alpha_pal_imb(); \ 353 alpha_pal_imb(); \
351 } \ 354 } \
352} while (0) 355} while (0)
353 356
354/* 357/*
355 * pmap-specific data store in the vm_page structure. 358 * pmap-specific data store in the vm_page structure.
356 */ 359 */
357#define __HAVE_VM_PAGE_MD 360#define __HAVE_VM_PAGE_MD
358struct vm_page_md { 361struct vm_page_md {
359 struct pv_entry *pvh_list; /* pv_entry list */ 362 struct pv_entry *pvh_list; /* pv_entry list */
360 int pvh_attrs; /* page attributes */ 363 int pvh_attrs; /* page attributes */
361 unsigned pvh_refcnt; 364 unsigned pvh_refcnt;
362}; 365};
363 366
364#define VM_MDPAGE_INIT(pg) \ 367#define VM_MDPAGE_INIT(pg) \
365do { \ 368do { \
366 (pg)->mdpage.pvh_list = NULL; \ 369 (pg)->mdpage.pvh_list = NULL; \
367 (pg)->mdpage.pvh_refcnt = 0; \ 370 (pg)->mdpage.pvh_refcnt = 0; \
368} while (/*CONSTCOND*/0) 371} while (/*CONSTCOND*/0)
369 372
370#endif /* _KERNEL */ 373#endif /* _KERNEL */
371 374
372#endif /* _PMAP_MACHINE_ */ 375#endif /* _PMAP_MACHINE_ */