pmap_private.h revision 1.3 1 1.3 riastrad /* $NetBSD: pmap_private.h,v 1.3 2022/09/13 09:40:17 riastradh Exp $ */
2 1.1 riastrad
3 1.1 riastrad /*
4 1.1 riastrad * Copyright (c) 1997 Charles D. Cranor and Washington University.
5 1.1 riastrad * All rights reserved.
6 1.1 riastrad *
7 1.1 riastrad * Redistribution and use in source and binary forms, with or without
8 1.1 riastrad * modification, are permitted provided that the following conditions
9 1.1 riastrad * are met:
10 1.1 riastrad * 1. Redistributions of source code must retain the above copyright
11 1.1 riastrad * notice, this list of conditions and the following disclaimer.
12 1.1 riastrad * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 riastrad * notice, this list of conditions and the following disclaimer in the
14 1.1 riastrad * documentation and/or other materials provided with the distribution.
15 1.1 riastrad *
16 1.1 riastrad * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 1.1 riastrad * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 1.1 riastrad * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 1.1 riastrad * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 1.1 riastrad * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 1.1 riastrad * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 1.1 riastrad * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 1.1 riastrad * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 1.1 riastrad * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 1.1 riastrad * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 1.1 riastrad */
27 1.1 riastrad
28 1.1 riastrad /*
29 1.1 riastrad * Copyright (c) 2001 Wasabi Systems, Inc.
30 1.1 riastrad * All rights reserved.
31 1.1 riastrad *
32 1.1 riastrad * Written by Frank van der Linden for Wasabi Systems, Inc.
33 1.1 riastrad *
34 1.1 riastrad * Redistribution and use in source and binary forms, with or without
35 1.1 riastrad * modification, are permitted provided that the following conditions
36 1.1 riastrad * are met:
37 1.1 riastrad * 1. Redistributions of source code must retain the above copyright
38 1.1 riastrad * notice, this list of conditions and the following disclaimer.
39 1.1 riastrad * 2. Redistributions in binary form must reproduce the above copyright
40 1.1 riastrad * notice, this list of conditions and the following disclaimer in the
41 1.1 riastrad * documentation and/or other materials provided with the distribution.
42 1.1 riastrad * 3. All advertising materials mentioning features or use of this software
43 1.1 riastrad * must display the following acknowledgement:
44 1.1 riastrad * This product includes software developed for the NetBSD Project by
45 1.1 riastrad * Wasabi Systems, Inc.
46 1.1 riastrad * 4. The name of Wasabi Systems, Inc. may not be used to endorse
47 1.1 riastrad * or promote products derived from this software without specific prior
48 1.1 riastrad * written permission.
49 1.1 riastrad *
50 1.1 riastrad * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
51 1.1 riastrad * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
52 1.1 riastrad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
53 1.1 riastrad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
54 1.1 riastrad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
55 1.1 riastrad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
56 1.1 riastrad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
57 1.1 riastrad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
58 1.1 riastrad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
59 1.1 riastrad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
60 1.1 riastrad * POSSIBILITY OF SUCH DAMAGE.
61 1.1 riastrad */
62 1.1 riastrad
63 1.1 riastrad #ifndef _X86_PMAP_PRIVATE_H_
64 1.1 riastrad #define _X86_PMAP_PRIVATE_H_
65 1.1 riastrad
66 1.1 riastrad #ifndef _MACHINE_PMAP_PRIVATE_H_X86
67 1.1 riastrad #error Include machine/pmap_private.h, not x86/pmap_private.h.
68 1.1 riastrad #endif
69 1.1 riastrad
70 1.1 riastrad #ifdef _KERNEL_OPT
71 1.1 riastrad #include "opt_svs.h"
72 1.1 riastrad #endif
73 1.1 riastrad
74 1.1 riastrad #include <sys/param.h>
75 1.1 riastrad #include <sys/types.h>
76 1.1 riastrad
77 1.2 riastrad #include <sys/kcpuset.h>
78 1.1 riastrad #include <sys/mutex.h>
79 1.1 riastrad #include <sys/pool.h>
80 1.1 riastrad #include <sys/queue.h>
81 1.2 riastrad #include <sys/rwlock.h>
82 1.1 riastrad
83 1.3 riastrad #include <machine/cpufunc.h>
84 1.1 riastrad #include <machine/pte.h>
85 1.1 riastrad #include <machine/vmparam.h>
86 1.1 riastrad
87 1.2 riastrad #include <uvm/uvm_object.h>
88 1.1 riastrad #include <uvm/uvm_pmap.h>
89 1.1 riastrad
90 1.1 riastrad struct pmap;
91 1.1 riastrad
92 1.1 riastrad #define SLAREA_USER 0
93 1.1 riastrad #define SLAREA_PTE 1
94 1.1 riastrad #define SLAREA_MAIN 2
95 1.1 riastrad #define SLAREA_PCPU 3
96 1.1 riastrad #define SLAREA_DMAP 4
97 1.1 riastrad #define SLAREA_HYPV 5
98 1.1 riastrad #define SLAREA_ASAN 6
99 1.1 riastrad #define SLAREA_MSAN 7
100 1.1 riastrad #define SLAREA_KERN 8
101 1.1 riastrad #define SLSPACE_NAREAS 9
102 1.1 riastrad
103 1.1 riastrad struct slotspace {
104 1.1 riastrad struct {
105 1.1 riastrad size_t sslot; /* start slot */
106 1.1 riastrad size_t nslot; /* # of slots */
107 1.1 riastrad bool active; /* area is active */
108 1.1 riastrad } area[SLSPACE_NAREAS];
109 1.1 riastrad };
110 1.1 riastrad
111 1.1 riastrad extern struct slotspace slotspace;
112 1.1 riastrad
113 1.1 riastrad #include <x86/gdt.h>
114 1.1 riastrad
115 1.1 riastrad struct pcpu_entry {
116 1.1 riastrad uint8_t gdt[MAXGDTSIZ];
117 1.1 riastrad uint8_t ldt[MAX_USERLDT_SIZE];
118 1.1 riastrad uint8_t idt[PAGE_SIZE];
119 1.1 riastrad uint8_t tss[PAGE_SIZE];
120 1.1 riastrad uint8_t ist0[PAGE_SIZE];
121 1.1 riastrad uint8_t ist1[PAGE_SIZE];
122 1.1 riastrad uint8_t ist2[PAGE_SIZE];
123 1.1 riastrad uint8_t ist3[PAGE_SIZE];
124 1.1 riastrad uint8_t rsp0[2 * PAGE_SIZE];
125 1.1 riastrad } __packed;
126 1.1 riastrad
127 1.1 riastrad struct pcpu_area {
128 1.1 riastrad #ifdef SVS
129 1.1 riastrad uint8_t utls[PAGE_SIZE];
130 1.1 riastrad #endif
131 1.1 riastrad uint8_t ldt[PAGE_SIZE];
132 1.1 riastrad struct pcpu_entry ent[MAXCPUS];
133 1.1 riastrad } __packed;
134 1.1 riastrad
135 1.1 riastrad extern struct pcpu_area *pcpuarea;
136 1.1 riastrad
137 1.1 riastrad #define PMAP_PCID_KERN 0
138 1.1 riastrad #define PMAP_PCID_USER 1
139 1.1 riastrad
140 1.1 riastrad /*
141 1.1 riastrad * pmap data structures: see pmap.c for details of locking.
142 1.1 riastrad */
143 1.1 riastrad
144 1.1 riastrad /*
145 1.1 riastrad * we maintain a list of all non-kernel pmaps
146 1.1 riastrad */
147 1.1 riastrad
148 1.1 riastrad LIST_HEAD(pmap_head, pmap); /* struct pmap_head: head of a pmap list */
149 1.1 riastrad
150 1.1 riastrad /*
151 1.1 riastrad * linked list of all non-kernel pmaps
152 1.1 riastrad */
153 1.1 riastrad extern struct pmap_head pmaps;
154 1.1 riastrad extern kmutex_t pmaps_lock; /* protects pmaps */
155 1.1 riastrad
156 1.1 riastrad /*
157 1.1 riastrad * pool_cache(9) that pmaps are allocated from
158 1.1 riastrad */
159 1.1 riastrad extern struct pool_cache pmap_cache;
160 1.1 riastrad
161 1.2 riastrad /*
162 1.2 riastrad * the pmap structure
163 1.2 riastrad *
164 1.2 riastrad * note that the pm_obj contains the lock pointer, the reference count,
165 1.2 riastrad * page list, and number of PTPs within the pmap.
166 1.2 riastrad *
167 1.2 riastrad * pm_lock is the same as the lock for vm object 0. Changes to
168 1.2 riastrad * the other objects may only be made if that lock has been taken
169 1.2 riastrad * (the other object locks are only used when uvm_pagealloc is called)
170 1.2 riastrad */
171 1.2 riastrad
172 1.2 riastrad struct pv_page;
173 1.2 riastrad
174 1.2 riastrad struct pmap {
175 1.2 riastrad struct uvm_object pm_obj[PTP_LEVELS-1];/* objects for lvl >= 1) */
176 1.2 riastrad LIST_ENTRY(pmap) pm_list; /* list of all pmaps */
177 1.2 riastrad pd_entry_t *pm_pdir; /* VA of PD */
178 1.2 riastrad paddr_t pm_pdirpa[PDP_SIZE]; /* PA of PDs (read-only after create) */
179 1.2 riastrad struct vm_page *pm_ptphint[PTP_LEVELS-1];
180 1.2 riastrad /* pointer to a PTP in our pmap */
181 1.2 riastrad struct pmap_statistics pm_stats; /* pmap stats */
182 1.2 riastrad struct pv_entry *pm_pve; /* spare pv_entry */
183 1.2 riastrad LIST_HEAD(, pv_page) pm_pvp_part;
184 1.2 riastrad LIST_HEAD(, pv_page) pm_pvp_empty;
185 1.2 riastrad LIST_HEAD(, pv_page) pm_pvp_full;
186 1.2 riastrad
187 1.2 riastrad #if !defined(__x86_64__)
188 1.2 riastrad vaddr_t pm_hiexec; /* highest executable mapping */
189 1.2 riastrad #endif /* !defined(__x86_64__) */
190 1.2 riastrad
191 1.2 riastrad union descriptor *pm_ldt; /* user-set LDT */
192 1.2 riastrad size_t pm_ldt_len; /* XXX unused, remove */
193 1.2 riastrad int pm_ldt_sel; /* LDT selector */
194 1.2 riastrad
195 1.2 riastrad kcpuset_t *pm_cpus; /* mask of CPUs using pmap */
196 1.2 riastrad kcpuset_t *pm_kernel_cpus; /* mask of CPUs using kernel part
197 1.2 riastrad of pmap */
198 1.2 riastrad kcpuset_t *pm_xen_ptp_cpus; /* mask of CPUs which have this pmap's
199 1.2 riastrad ptp mapped */
200 1.2 riastrad uint64_t pm_ncsw; /* for assertions */
201 1.2 riastrad LIST_HEAD(,vm_page) pm_gc_ptp; /* PTPs queued for free */
202 1.2 riastrad
203 1.2 riastrad /* Used by NVMM and Xen */
204 1.2 riastrad int (*pm_enter)(struct pmap *, vaddr_t, paddr_t, vm_prot_t, u_int);
205 1.2 riastrad bool (*pm_extract)(struct pmap *, vaddr_t, paddr_t *);
206 1.2 riastrad void (*pm_remove)(struct pmap *, vaddr_t, vaddr_t);
207 1.2 riastrad int (*pm_sync_pv)(struct vm_page *, vaddr_t, paddr_t, int, uint8_t *,
208 1.2 riastrad pt_entry_t *);
209 1.2 riastrad void (*pm_pp_remove_ent)(struct pmap *, struct vm_page *, pt_entry_t,
210 1.2 riastrad vaddr_t);
211 1.2 riastrad void (*pm_write_protect)(struct pmap *, vaddr_t, vaddr_t, vm_prot_t);
212 1.2 riastrad void (*pm_unwire)(struct pmap *, vaddr_t);
213 1.2 riastrad
214 1.2 riastrad void (*pm_tlb_flush)(struct pmap *);
215 1.2 riastrad void *pm_data;
216 1.2 riastrad
217 1.2 riastrad kmutex_t pm_lock /* locks for pm_objs */
218 1.2 riastrad __aligned(64); /* give lock own cache line */
219 1.2 riastrad krwlock_t pm_dummy_lock; /* ugly hack for abusing uvm_object */
220 1.2 riastrad };
221 1.2 riastrad
222 1.1 riastrad /* macro to access pm_pdirpa slots */
223 1.1 riastrad #ifdef PAE
224 1.1 riastrad #define pmap_pdirpa(pmap, index) \
225 1.1 riastrad ((pmap)->pm_pdirpa[l2tol3(index)] + l2tol2(index) * sizeof(pd_entry_t))
226 1.1 riastrad #else
227 1.1 riastrad #define pmap_pdirpa(pmap, index) \
228 1.1 riastrad ((pmap)->pm_pdirpa[0] + (index) * sizeof(pd_entry_t))
229 1.1 riastrad #endif
230 1.1 riastrad
231 1.1 riastrad /*
232 1.1 riastrad * global kernel variables
233 1.1 riastrad */
234 1.1 riastrad
235 1.1 riastrad /*
236 1.1 riastrad * PDPpaddr is the physical address of the kernel's PDP.
237 1.1 riastrad * - i386 non-PAE and amd64: PDPpaddr corresponds directly to the %cr3
238 1.1 riastrad * value associated to the kernel process, proc0.
239 1.1 riastrad * - i386 PAE: it still represents the PA of the kernel's PDP (L2). Due to
240 1.1 riastrad * the L3 PD, it cannot be considered as the equivalent of a %cr3 any more.
241 1.1 riastrad * - Xen: it corresponds to the PFN of the kernel's PDP.
242 1.1 riastrad */
243 1.1 riastrad extern u_long PDPpaddr;
244 1.1 riastrad
245 1.1 riastrad extern pd_entry_t pmap_pg_g; /* do we support PTE_G? */
246 1.1 riastrad extern pd_entry_t pmap_pg_nx; /* do we support PTE_NX? */
247 1.1 riastrad extern int pmap_largepages;
248 1.1 riastrad extern long nkptp[PTP_LEVELS];
249 1.1 riastrad
250 1.1 riastrad #define pmap_valid_entry(E) ((E) & PTE_P) /* is PDE or PTE valid? */
251 1.1 riastrad
252 1.1 riastrad void pmap_map_ptes(struct pmap *, struct pmap **, pd_entry_t **,
253 1.1 riastrad pd_entry_t * const **);
254 1.1 riastrad void pmap_unmap_ptes(struct pmap *, struct pmap *);
255 1.1 riastrad
256 1.1 riastrad bool pmap_pdes_valid(vaddr_t, pd_entry_t * const *, pd_entry_t *,
257 1.1 riastrad int *lastlvl);
258 1.1 riastrad
259 1.1 riastrad bool pmap_is_curpmap(struct pmap *);
260 1.1 riastrad
261 1.1 riastrad void pmap_ept_transform(struct pmap *);
262 1.1 riastrad
263 1.1 riastrad #ifndef __HAVE_DIRECT_MAP
264 1.1 riastrad void pmap_vpage_cpu_init(struct cpu_info *);
265 1.1 riastrad #endif
266 1.1 riastrad vaddr_t slotspace_rand(int, size_t, size_t, size_t, vaddr_t);
267 1.1 riastrad
268 1.1 riastrad vaddr_t reserve_dumppages(vaddr_t); /* XXX: not a pmap fn */
269 1.1 riastrad
270 1.1 riastrad typedef enum tlbwhy {
271 1.1 riastrad TLBSHOOT_REMOVE_ALL,
272 1.1 riastrad TLBSHOOT_KENTER,
273 1.1 riastrad TLBSHOOT_KREMOVE,
274 1.1 riastrad TLBSHOOT_FREE_PTP,
275 1.1 riastrad TLBSHOOT_REMOVE_PTE,
276 1.1 riastrad TLBSHOOT_SYNC_PV,
277 1.1 riastrad TLBSHOOT_WRITE_PROTECT,
278 1.1 riastrad TLBSHOOT_ENTER,
279 1.1 riastrad TLBSHOOT_NVMM,
280 1.1 riastrad TLBSHOOT_BUS_DMA,
281 1.1 riastrad TLBSHOOT_BUS_SPACE,
282 1.1 riastrad TLBSHOOT__MAX,
283 1.1 riastrad } tlbwhy_t;
284 1.1 riastrad
285 1.1 riastrad void pmap_tlb_init(void);
286 1.1 riastrad void pmap_tlb_cpu_init(struct cpu_info *);
287 1.1 riastrad void pmap_tlb_shootdown(pmap_t, vaddr_t, pt_entry_t, tlbwhy_t);
288 1.1 riastrad void pmap_tlb_shootnow(void);
289 1.1 riastrad void pmap_tlb_intr(void);
290 1.1 riastrad
291 1.1 riastrad /*
292 1.1 riastrad * inline functions
293 1.1 riastrad */
294 1.1 riastrad
295 1.1 riastrad /*
296 1.1 riastrad * pmap_update_pg: flush one page from the TLB (or flush the whole thing
297 1.1 riastrad * if hardware doesn't support one-page flushing)
298 1.1 riastrad */
299 1.1 riastrad
300 1.1 riastrad __inline static void __unused
301 1.1 riastrad pmap_update_pg(vaddr_t va)
302 1.1 riastrad {
303 1.1 riastrad invlpg(va);
304 1.1 riastrad }
305 1.1 riastrad
306 1.1 riastrad /*
307 1.1 riastrad * various address inlines
308 1.1 riastrad *
309 1.1 riastrad * vtopte: return a pointer to the PTE mapping a VA, works only for
310 1.1 riastrad * user and PT addresses
311 1.1 riastrad *
312 1.1 riastrad * kvtopte: return a pointer to the PTE mapping a kernel VA
313 1.1 riastrad */
314 1.1 riastrad
315 1.1 riastrad #include <lib/libkern/libkern.h>
316 1.1 riastrad
317 1.1 riastrad static __inline pt_entry_t * __unused
318 1.1 riastrad vtopte(vaddr_t va)
319 1.1 riastrad {
320 1.1 riastrad
321 1.1 riastrad KASSERT(va < VM_MIN_KERNEL_ADDRESS);
322 1.1 riastrad
323 1.1 riastrad return (PTE_BASE + pl1_i(va));
324 1.1 riastrad }
325 1.1 riastrad
326 1.1 riastrad static __inline pt_entry_t * __unused
327 1.1 riastrad kvtopte(vaddr_t va)
328 1.1 riastrad {
329 1.1 riastrad pd_entry_t *pde;
330 1.1 riastrad
331 1.1 riastrad KASSERT(va >= VM_MIN_KERNEL_ADDRESS);
332 1.1 riastrad
333 1.1 riastrad pde = L2_BASE + pl2_i(va);
334 1.1 riastrad if (*pde & PTE_PS)
335 1.1 riastrad return ((pt_entry_t *)pde);
336 1.1 riastrad
337 1.1 riastrad return (PTE_BASE + pl1_i(va));
338 1.1 riastrad }
339 1.1 riastrad
340 1.1 riastrad #ifdef XENPV
341 1.1 riastrad #include <sys/bitops.h>
342 1.1 riastrad
343 1.1 riastrad #define XPTE_MASK L1_FRAME
344 1.1 riastrad /* Selects the index of a PTE in (A)PTE_BASE */
345 1.1 riastrad #define XPTE_SHIFT (L1_SHIFT - ilog2(sizeof(pt_entry_t)))
346 1.1 riastrad
347 1.1 riastrad /* PTE access inline functions */
348 1.1 riastrad
349 1.1 riastrad /*
350 1.1 riastrad * Get the machine address of the pointed pte
351 1.1 riastrad * We use hardware MMU to get value so works only for levels 1-3
352 1.1 riastrad */
353 1.1 riastrad
354 1.1 riastrad static __inline paddr_t
355 1.1 riastrad xpmap_ptetomach(pt_entry_t *pte)
356 1.1 riastrad {
357 1.1 riastrad pt_entry_t *up_pte;
358 1.1 riastrad vaddr_t va = (vaddr_t) pte;
359 1.1 riastrad
360 1.1 riastrad va = ((va & XPTE_MASK) >> XPTE_SHIFT) | (vaddr_t) PTE_BASE;
361 1.1 riastrad up_pte = (pt_entry_t *) va;
362 1.1 riastrad
363 1.1 riastrad return (paddr_t) (((*up_pte) & PTE_FRAME) + (((vaddr_t) pte) & (~PTE_FRAME & ~VA_SIGN_MASK)));
364 1.1 riastrad }
365 1.1 riastrad
366 1.1 riastrad /* Xen helpers to change bits of a pte */
367 1.1 riastrad #define XPMAP_UPDATE_DIRECT 1 /* Update direct map entry flags too */
368 1.1 riastrad
369 1.1 riastrad paddr_t vtomach(vaddr_t);
370 1.1 riastrad #define vtomfn(va) (vtomach(va) >> PAGE_SHIFT)
371 1.1 riastrad #endif /* XENPV */
372 1.1 riastrad
373 1.1 riastrad #ifdef __HAVE_PCPU_AREA
374 1.1 riastrad extern struct pcpu_area *pcpuarea;
375 1.1 riastrad #define PDIR_SLOT_PCPU 510
376 1.1 riastrad #define PMAP_PCPU_BASE (VA_SIGN_NEG((PDIR_SLOT_PCPU * NBPD_L4)))
377 1.1 riastrad #endif
378 1.1 riastrad
379 1.1 riastrad void svs_quad_copy(void *, void *, long);
380 1.1 riastrad
381 1.1 riastrad #endif /* _X86_PMAP_PRIVATE_H_ */
382