1*081fc2e0Sjsg /* $OpenBSD: pmap.h,v 1.91 2024/11/08 01:57:34 jsg Exp $ */ 2f5df1827Smickey /* $NetBSD: pmap.h,v 1.1 2003/04/26 18:39:46 fvdl Exp $ */ 3f5df1827Smickey 4f5df1827Smickey /* 5f5df1827Smickey * Copyright (c) 1997 Charles D. Cranor and Washington University. 6f5df1827Smickey * All rights reserved. 7f5df1827Smickey * 8f5df1827Smickey * Redistribution and use in source and binary forms, with or without 9f5df1827Smickey * modification, are permitted provided that the following conditions 10f5df1827Smickey * are met: 11f5df1827Smickey * 1. Redistributions of source code must retain the above copyright 12f5df1827Smickey * notice, this list of conditions and the following disclaimer. 13f5df1827Smickey * 2. Redistributions in binary form must reproduce the above copyright 14f5df1827Smickey * notice, this list of conditions and the following disclaimer in the 15f5df1827Smickey * documentation and/or other materials provided with the distribution. 16f5df1827Smickey * 17f5df1827Smickey * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18f5df1827Smickey * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19f5df1827Smickey * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20f5df1827Smickey * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21f5df1827Smickey * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22f5df1827Smickey * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23f5df1827Smickey * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24f5df1827Smickey * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25f5df1827Smickey * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26f5df1827Smickey * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27f5df1827Smickey */ 28f5df1827Smickey 29f5df1827Smickey /* 30f5df1827Smickey * Copyright (c) 2001 Wasabi Systems, Inc. 31f5df1827Smickey * All rights reserved. 32f5df1827Smickey * 33f5df1827Smickey * Written by Frank van der Linden for Wasabi Systems, Inc. 34f5df1827Smickey * 35f5df1827Smickey * Redistribution and use in source and binary forms, with or without 36f5df1827Smickey * modification, are permitted provided that the following conditions 37f5df1827Smickey * are met: 38f5df1827Smickey * 1. Redistributions of source code must retain the above copyright 39f5df1827Smickey * notice, this list of conditions and the following disclaimer. 40f5df1827Smickey * 2. Redistributions in binary form must reproduce the above copyright 41f5df1827Smickey * notice, this list of conditions and the following disclaimer in the 42f5df1827Smickey * documentation and/or other materials provided with the distribution. 43f5df1827Smickey * 3. All advertising materials mentioning features or use of this software 44f5df1827Smickey * must display the following acknowledgement: 45f5df1827Smickey * This product includes software developed for the NetBSD Project by 46f5df1827Smickey * Wasabi Systems, Inc. 47f5df1827Smickey * 4. The name of Wasabi Systems, Inc. may not be used to endorse 48f5df1827Smickey * or promote products derived from this software without specific prior 49f5df1827Smickey * written permission. 50f5df1827Smickey * 51f5df1827Smickey * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 52f5df1827Smickey * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 53f5df1827Smickey * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 54f5df1827Smickey * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 55f5df1827Smickey * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 56f5df1827Smickey * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 57f5df1827Smickey * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 58f5df1827Smickey * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 59f5df1827Smickey * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 60f5df1827Smickey * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 61f5df1827Smickey * POSSIBILITY OF SUCH DAMAGE. 62f5df1827Smickey */ 63f5df1827Smickey 64f5df1827Smickey /* 65f5df1827Smickey * pmap.h: see pmap.c for the history of this pmap module. 66f5df1827Smickey */ 67f5df1827Smickey 682fa72412Spirofti #ifndef _MACHINE_PMAP_H_ 692fa72412Spirofti #define _MACHINE_PMAP_H_ 70f5df1827Smickey 71f5df1827Smickey #ifndef _LOCORE 7243d4f7a5Sderaadt #ifdef _KERNEL 7301852f87Skettenis #include <lib/libkern/libkern.h> /* for KASSERT() */ 74f5df1827Smickey #include <machine/cpufunc.h> 7543d4f7a5Sderaadt #endif /* _KERNEL */ 760c33c81eSkettenis #include <sys/mutex.h> 77f5df1827Smickey #include <uvm/uvm_object.h> 7843d4f7a5Sderaadt #include <machine/pte.h> 79f5df1827Smickey #endif 80f5df1827Smickey 81f5df1827Smickey /* 82f5df1827Smickey * The x86_64 pmap module closely resembles the i386 one. It uses 83f70b48dcSsf * the same recursive entry scheme. See the i386 pmap.h for a 84f70b48dcSsf * description. The alternate area trick for accessing non-current 85f70b48dcSsf * pmaps has been removed, though, because it performs badly on SMP 86f70b48dcSsf * systems. 87f70b48dcSsf * The most obvious difference to i386 is that 2 extra levels of page 88f70b48dcSsf * table need to be dealt with. The level 1 page table pages are at: 89f5df1827Smickey * 90f5df1827Smickey * l1: 0x00007f8000000000 - 0x00007fffffffffff (39 bits, needs PML4 entry) 91f5df1827Smickey * 920a53f50bSguenther * The other levels are kept as physical pages in 3 UVM objects and are 93f5df1827Smickey * temporarily mapped for virtual access when needed. 94f5df1827Smickey * 950a53f50bSguenther * The other obvious difference from i386 is that it has a direct map of all 960a53f50bSguenther * physical memory in the VA range: 970a53f50bSguenther * 98d2fed533Smlarkin * 0xfffffd8000000000 - 0xffffff7fffffffff 99f70b48dcSsf * 100f70b48dcSsf * The direct map is used in some cases to access PTEs of non-current pmaps. 1010a53f50bSguenther * 102f5df1827Smickey * Note that address space is signed, so the layout for 48 bits is: 103f5df1827Smickey * 104f5df1827Smickey * +---------------------------------+ 0xffffffffffffffff 1050a53f50bSguenther * | Kernel Image | 106f5df1827Smickey * +---------------------------------+ 0xffffff8000000000 1070a53f50bSguenther * | Direct Map | 108d2fed533Smlarkin * +---------------------------------+ 0xfffffd8000000000 109f5df1827Smickey * ~ ~ 110f5df1827Smickey * | | 111f5df1827Smickey * | Kernel Space | 112f5df1827Smickey * | | 113f5df1827Smickey * | | 114ff894b95Shshoexer * +---------------------------------+ 0xffff800000000000 = 0x0000800000000000 115c97049d6Sart * | L1 table (PTE pages) | 116f5df1827Smickey * +---------------------------------+ 0x00007f8000000000 117f5df1827Smickey * ~ ~ 118f5df1827Smickey * | | 119f5df1827Smickey * | User Space | 120f5df1827Smickey * | | 121f5df1827Smickey * | | 122f5df1827Smickey * +---------------------------------+ 0x0000000000000000 123f5df1827Smickey * 124ff894b95Shshoexer * In other words, there is a 'VA hole' at 0x0000800000000000 - 125f5df1827Smickey * 0xffff800000000000 which will trap, just as on, for example, 126f5df1827Smickey * sparcv9. 127f5df1827Smickey * 128f5df1827Smickey * The unused space can be used if needed, but it adds a little more 129f5df1827Smickey * complexity to the calculations. 130f5df1827Smickey */ 131f5df1827Smickey 132f5df1827Smickey /* 133f5df1827Smickey * Mask to get rid of the sign-extended part of addresses. 134f5df1827Smickey */ 135f5df1827Smickey #define VA_SIGN_MASK 0xffff000000000000 136f5df1827Smickey #define VA_SIGN_NEG(va) ((va) | VA_SIGN_MASK) 137f5df1827Smickey /* 138f5df1827Smickey * XXXfvdl this one's not right. 139f5df1827Smickey */ 140f5df1827Smickey #define VA_SIGN_POS(va) ((va) & ~VA_SIGN_MASK) 141f5df1827Smickey 142f5df1827Smickey #define L4_SLOT_PTE 255 143f5df1827Smickey #define L4_SLOT_KERN 256 144f5df1827Smickey #define L4_SLOT_KERNBASE 511 145d2fed533Smlarkin #define NUM_L4_SLOT_DIRECT 4 146d2fed533Smlarkin #define L4_SLOT_DIRECT (L4_SLOT_KERNBASE - NUM_L4_SLOT_DIRECT) 1474034e82eSkettenis #define L4_SLOT_EARLY (L4_SLOT_DIRECT - 1) 148f5df1827Smickey 149f5df1827Smickey #define PDIR_SLOT_KERN L4_SLOT_KERN 150f5df1827Smickey #define PDIR_SLOT_PTE L4_SLOT_PTE 1514814b8ceSart #define PDIR_SLOT_DIRECT L4_SLOT_DIRECT 1524034e82eSkettenis #define PDIR_SLOT_EARLY L4_SLOT_EARLY 153f5df1827Smickey 154f5df1827Smickey /* 155f5df1827Smickey * the following defines give the virtual addresses of various MMU 156f5df1827Smickey * data structures: 157f70b48dcSsf * PTE_BASE: the base VA of the linear PTE mappings 158f70b48dcSsf * PDP_PDE: the VA of the PDE that points back to the PDP 159f5df1827Smickey * 160f5df1827Smickey */ 161f5df1827Smickey 162f5df1827Smickey #define PTE_BASE ((pt_entry_t *) (L4_SLOT_PTE * NBPD_L4)) 1634814b8ceSart #define PMAP_DIRECT_BASE (VA_SIGN_NEG((L4_SLOT_DIRECT * NBPD_L4))) 164d2fed533Smlarkin #define PMAP_DIRECT_END (VA_SIGN_NEG(((L4_SLOT_DIRECT + \ 165d2fed533Smlarkin NUM_L4_SLOT_DIRECT) * NBPD_L4))) 166f5df1827Smickey 167f5df1827Smickey #define L1_BASE PTE_BASE 168f5df1827Smickey 169f5df1827Smickey #define L2_BASE ((pd_entry_t *)((char *)L1_BASE + L4_SLOT_PTE * NBPD_L3)) 170f5df1827Smickey #define L3_BASE ((pd_entry_t *)((char *)L2_BASE + L4_SLOT_PTE * NBPD_L2)) 171f5df1827Smickey #define L4_BASE ((pd_entry_t *)((char *)L3_BASE + L4_SLOT_PTE * NBPD_L1)) 172f5df1827Smickey 173f5df1827Smickey #define PDP_PDE (L4_BASE + PDIR_SLOT_PTE) 174f5df1827Smickey 175f5df1827Smickey #define PDP_BASE L4_BASE 176f5df1827Smickey 177f5df1827Smickey #define NKL4_MAX_ENTRIES (unsigned long)1 178f5df1827Smickey #define NKL3_MAX_ENTRIES (unsigned long)(NKL4_MAX_ENTRIES * 512) 179f5df1827Smickey #define NKL2_MAX_ENTRIES (unsigned long)(NKL3_MAX_ENTRIES * 512) 180f5df1827Smickey #define NKL1_MAX_ENTRIES (unsigned long)(NKL2_MAX_ENTRIES * 512) 181f5df1827Smickey 182f5df1827Smickey #define NKL4_KIMG_ENTRIES 1 183f5df1827Smickey #define NKL3_KIMG_ENTRIES 1 184bfaa8ac6Smlarkin #define NKL2_KIMG_ENTRIES 64 185f5df1827Smickey 186d2fed533Smlarkin /* number of pages of direct map entries set up by locore0.S */ 187f00c9240Sart #define NDML4_ENTRIES 1 188f00c9240Sart #define NDML3_ENTRIES 1 189f00c9240Sart #define NDML2_ENTRIES 4 /* 4GB */ 190f00c9240Sart 191f5df1827Smickey /* 192f5df1827Smickey * Since kva space is below the kernel in its entirety, we start off 193f5df1827Smickey * with zero entries on each level. 194f5df1827Smickey */ 195f5df1827Smickey #define NKL4_START_ENTRIES 0 196f5df1827Smickey #define NKL3_START_ENTRIES 0 197f5df1827Smickey #define NKL2_START_ENTRIES 0 198f5df1827Smickey #define NKL1_START_ENTRIES 0 /* XXX */ 199f5df1827Smickey 200f5df1827Smickey #define NTOPLEVEL_PDES (PAGE_SIZE / (sizeof (pd_entry_t))) 201f5df1827Smickey 202f5df1827Smickey #define NPDPG (PAGE_SIZE / sizeof (pd_entry_t)) 203f5df1827Smickey 204f5df1827Smickey /* 205f5df1827Smickey * pl*_pi: index in the ptp page for a pde mapping a VA. 206f5df1827Smickey * (pl*_i below is the index in the virtual array of all pdes per level) 207f5df1827Smickey */ 208f5df1827Smickey #define pl1_pi(VA) (((VA_SIGN_POS(VA)) & L1_MASK) >> L1_SHIFT) 209f5df1827Smickey #define pl2_pi(VA) (((VA_SIGN_POS(VA)) & L2_MASK) >> L2_SHIFT) 210f5df1827Smickey #define pl3_pi(VA) (((VA_SIGN_POS(VA)) & L3_MASK) >> L3_SHIFT) 211f5df1827Smickey #define pl4_pi(VA) (((VA_SIGN_POS(VA)) & L4_MASK) >> L4_SHIFT) 212f5df1827Smickey 213f5df1827Smickey /* 214f5df1827Smickey * pl*_i: generate index into pde/pte arrays in virtual space 215f5df1827Smickey */ 216f5df1827Smickey #define pl1_i(VA) (((VA_SIGN_POS(VA)) & L1_FRAME) >> L1_SHIFT) 217f5df1827Smickey #define pl2_i(VA) (((VA_SIGN_POS(VA)) & L2_FRAME) >> L2_SHIFT) 218f5df1827Smickey #define pl3_i(VA) (((VA_SIGN_POS(VA)) & L3_FRAME) >> L3_SHIFT) 219f5df1827Smickey #define pl4_i(VA) (((VA_SIGN_POS(VA)) & L4_FRAME) >> L4_SHIFT) 220f5df1827Smickey #define pl_i(va, lvl) \ 221f5df1827Smickey (((VA_SIGN_POS(va)) & ptp_masks[(lvl)-1]) >> ptp_shifts[(lvl)-1]) 222f5df1827Smickey 223f5df1827Smickey #define PTP_MASK_INITIALIZER { L1_FRAME, L2_FRAME, L3_FRAME, L4_FRAME } 224f5df1827Smickey #define PTP_SHIFT_INITIALIZER { L1_SHIFT, L2_SHIFT, L3_SHIFT, L4_SHIFT } 225f5df1827Smickey #define NKPTP_INITIALIZER { NKL1_START_ENTRIES, NKL2_START_ENTRIES, \ 226f5df1827Smickey NKL3_START_ENTRIES, NKL4_START_ENTRIES } 227f5df1827Smickey #define NKPTPMAX_INITIALIZER { NKL1_MAX_ENTRIES, NKL2_MAX_ENTRIES, \ 228f5df1827Smickey NKL3_MAX_ENTRIES, NKL4_MAX_ENTRIES } 229f5df1827Smickey #define NBPD_INITIALIZER { NBPD_L1, NBPD_L2, NBPD_L3, NBPD_L4 } 230f5df1827Smickey #define PDES_INITIALIZER { L2_BASE, L3_BASE, L4_BASE } 231f5df1827Smickey 232f5df1827Smickey /* 233f5df1827Smickey * PTP macros: 234f5df1827Smickey * a PTP's index is the PD index of the PDE that points to it 235f5df1827Smickey * a PTP's offset is the byte-offset in the PTE space that this PTP is at 236f5df1827Smickey * a PTP's VA is the first VA mapped by that PTP 237f5df1827Smickey */ 238f5df1827Smickey 239f5df1827Smickey #define ptp_va2o(va, lvl) (pl_i(va, (lvl)+1) * PAGE_SIZE) 240f5df1827Smickey 241f5df1827Smickey #define PTP_LEVELS 4 242f5df1827Smickey 243f5df1827Smickey /* 244f5df1827Smickey * PG_AVAIL usage: we make use of the ignored bits of the PTE 245f5df1827Smickey */ 246f5df1827Smickey 247f5df1827Smickey #define PG_W PG_AVAIL1 /* "wired" mapping */ 248f5df1827Smickey #define PG_PVLIST PG_AVAIL2 /* mapping has entry on pvlist */ 249f5df1827Smickey /* PG_AVAIL3 not used */ 250f5df1827Smickey 251f5df1827Smickey /* 252f95e373fSguenther * PCID assignments. 253f95e373fSguenther * The shootdown code assumes KERN, PROC, and PROC_INTEL are both 254f95e373fSguenther * consecutive and in that order. 255f95e373fSguenther */ 256f95e373fSguenther #define PCID_KERN 0 /* for pmap_kernel() */ 257f95e373fSguenther #define PCID_PROC 1 /* non-pmap_kernel(), U+K */ 258f95e373fSguenther #define PCID_PROC_INTEL 2 /* non-pmap_kernel(), U-K (meltdown) */ 259f95e373fSguenther #define PCID_TEMP 3 /* temp mapping of another non-pmap_kernel() */ 26040b59acfSkettenis #define PCID_EFI 4 /* EFI runtime services */ 261f95e373fSguenther 262f95e373fSguenther extern int pmap_use_pcid; /* non-zero if PCID support is enabled */ 263f95e373fSguenther 264f95e373fSguenther /* 265e62649fdSmlarkin * Number of PTEs per cache line. 8 byte pte, 64-byte cache line 266f5df1827Smickey * Used to avoid false sharing of cache lines. 267f5df1827Smickey */ 268f5df1827Smickey #define NPTECL 8 269f5df1827Smickey 270f5df1827Smickey 271f5df1827Smickey #if defined(_KERNEL) && !defined(_LOCORE) 272f5df1827Smickey /* 273f5df1827Smickey * pmap data structures: see pmap.c for details of locking. 274f5df1827Smickey */ 275f5df1827Smickey 276f5df1827Smickey struct pmap; 277f5df1827Smickey typedef struct pmap *pmap_t; 278f5df1827Smickey 279f5df1827Smickey /* 280f5df1827Smickey * we maintain a list of all non-kernel pmaps 281f5df1827Smickey */ 282f5df1827Smickey 283f5df1827Smickey LIST_HEAD(pmap_head, pmap); /* struct pmap_head: head of a pmap list */ 284f5df1827Smickey 285f5df1827Smickey /* 286f5df1827Smickey * the pmap structure 287f5df1827Smickey * 288f50dbc4bStedu * note that the pm_obj contains the reference count, 289f5df1827Smickey * page list, and number of PTPs within the pmap. 290f5df1827Smickey */ 291f5df1827Smickey 29263567820Smlarkin #define PMAP_TYPE_NORMAL 1 29363567820Smlarkin #define PMAP_TYPE_EPT 2 29463567820Smlarkin #define PMAP_TYPE_RVI 3 29563567820Smlarkin #define pmap_nested(pm) ((pm)->pm_type != PMAP_TYPE_NORMAL) 29630e2643aSdv #define pmap_is_ept(pm) ((pm)->pm_type == PMAP_TYPE_EPT) 29763567820Smlarkin 298f5df1827Smickey struct pmap { 2990c33c81eSkettenis struct mutex pm_mtx; 300f5df1827Smickey struct uvm_object pm_obj[PTP_LEVELS-1]; /* objects for lvl >= 1) */ 301f5df1827Smickey LIST_ENTRY(pmap) pm_list; /* list (lck by pm_list lock) */ 302b767b017Sguenther /* 303b767b017Sguenther * pm_pdir : VA of page table to be used when executing in 304b767b017Sguenther * privileged mode 305b767b017Sguenther * pm_pdirpa : PA of page table to be used when executing in 306b767b017Sguenther * privileged mode 307b767b017Sguenther * pm_pdir_intel : VA of special page table to be used when executing 308b767b017Sguenther * on an Intel CPU in usermode (no kernel mappings) 309b767b017Sguenther * pm_pdirpa_intel : PA of special page table to be used when executing 310b767b017Sguenther * on an Intel CPU in usermode (no kernel mappings) 311b767b017Sguenther */ 312b767b017Sguenther pd_entry_t *pm_pdir, *pm_pdir_intel; 313b767b017Sguenther paddr_t pm_pdirpa, pm_pdirpa_intel; 314b767b017Sguenther 315f5df1827Smickey struct vm_page *pm_ptphint[PTP_LEVELS-1]; 316f5df1827Smickey /* pointer to a PTP in our pmap */ 317f5df1827Smickey struct pmap_statistics pm_stats; /* pmap stats (lck by object lock) */ 318f5df1827Smickey 31963567820Smlarkin int pm_type; /* Type of pmap this is (PMAP_TYPE_x) */ 320a4cc50f2Smlarkin uint64_t eptp; /* cached EPTP (used by vmm) */ 321f5df1827Smickey }; 322f5df1827Smickey 32340b59acfSkettenis #define PMAP_EFI PMAP_MD0 3244fb10293Sbluhm #define PMAP_NOCRYPT PMAP_MD1 32540b59acfSkettenis 326f5df1827Smickey /* 327de00544fSoga * MD flags that we use for pmap_enter (in the pa): 328b7059877Soga */ 329de00544fSoga #define PMAP_PA_MASK ~((paddr_t)PAGE_MASK) /* to remove the flags */ 330de00544fSoga #define PMAP_NOCACHE 0x1 /* set the non-cacheable bit. */ 33107dfb2ccSoga #define PMAP_WC 0x2 /* set page write combining. */ 332b7059877Soga 333b7059877Soga /* 33493668d7cSart * We keep mod/ref flags in struct vm_page->pg_flags. 335f5df1827Smickey */ 33693668d7cSart #define PG_PMAP_MOD PG_PMAP0 33793668d7cSart #define PG_PMAP_REF PG_PMAP1 33807dfb2ccSoga #define PG_PMAP_WC PG_PMAP2 339f5df1827Smickey 34093668d7cSart /* 34193668d7cSart * for each managed physical page we maintain a list of <PMAP,VA>'s 34293668d7cSart * which it is mapped at. 34393668d7cSart */ 344f5df1827Smickey struct pv_entry { /* locked by its list's pvh_lock */ 345f5df1827Smickey struct pv_entry *pv_next; /* next entry */ 346f5df1827Smickey struct pmap *pv_pmap; /* the pmap */ 347f5df1827Smickey vaddr_t pv_va; /* the virtual address */ 348f5df1827Smickey struct vm_page *pv_ptp; /* the vm_page of the PTP */ 349f5df1827Smickey }; 350f5df1827Smickey 351f5df1827Smickey /* 352f5df1827Smickey * global kernel variables 353f5df1827Smickey */ 354f5df1827Smickey 355f5df1827Smickey extern struct pmap kernel_pmap_store; /* kernel pmap */ 356f5df1827Smickey 357118aa2cdSguenther extern long nkptp[]; 358118aa2cdSguenther 359118aa2cdSguenther extern const paddr_t ptp_masks[]; 360118aa2cdSguenther extern const int ptp_shifts[]; 361118aa2cdSguenther extern const long nbpd[], nkptpmax[]; 362f5df1827Smickey 363f5df1827Smickey /* 364f5df1827Smickey * macros 365f5df1827Smickey */ 366f5df1827Smickey 367f5df1827Smickey #define pmap_kernel() (&kernel_pmap_store) 368f5df1827Smickey #define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count) 369f5df1827Smickey #define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count) 370f5df1827Smickey #define pmap_update(pmap) /* nothing (yet) */ 371f5df1827Smickey 372f5df1827Smickey #define pmap_clear_modify(pg) pmap_clear_attrs(pg, PG_M) 373f5df1827Smickey #define pmap_clear_reference(pg) pmap_clear_attrs(pg, PG_U) 374f5df1827Smickey #define pmap_is_modified(pg) pmap_test_attrs(pg, PG_M) 375f5df1827Smickey #define pmap_is_referenced(pg) pmap_test_attrs(pg, PG_U) 376f5df1827Smickey #define pmap_valid_entry(E) ((E) & PG_V) /* is PDE or PTE valid? */ 377f5df1827Smickey 37865a6ef6dSkettenis #define pmap_proc_iflush(p,va,len) /* nothing */ 379bee7e938Sderaadt #define pmap_unuse_final(p) /* nothing */ 380120b8d62Smiod #define pmap_remove_holes(vm) do { /* nothing */ } while (0) 38165a6ef6dSkettenis 382f5df1827Smickey 383f5df1827Smickey /* 384f5df1827Smickey * prototypes 385f5df1827Smickey */ 386f5df1827Smickey 387163e3b03Smlarkin void map_tramps(void); /* machdep.c */ 3880f91bea7Sweingart paddr_t pmap_bootstrap(paddr_t, paddr_t); 38924f569d2Sjca void pmap_init_percpu(void); 390163e3b03Smlarkin void pmap_randomize(void); 391a821d2d9Smlarkin void pmap_randomize_level(pd_entry_t *, int); 39246ad639fSmpi int pmap_clear_attrs(struct vm_page *, unsigned long); 393f5df1827Smickey static void pmap_page_protect(struct vm_page *, vm_prot_t); 394f5df1827Smickey void pmap_page_remove (struct vm_page *); 395f5df1827Smickey static void pmap_protect(struct pmap *, vaddr_t, 396f5df1827Smickey vaddr_t, vm_prot_t); 397f5df1827Smickey void pmap_remove(struct pmap *, vaddr_t, vaddr_t); 39846ad639fSmpi int pmap_test_attrs(struct vm_page *, unsigned); 399f5df1827Smickey static void pmap_update_pg(vaddr_t); 400f5df1827Smickey void pmap_write_protect(struct pmap *, vaddr_t, 401f5df1827Smickey vaddr_t, vm_prot_t); 40286900c8aSstefan void pmap_fix_ept(struct pmap *, vaddr_t); 403f5df1827Smickey 4040f91bea7Sweingart paddr_t pmap_prealloc_lowmem_ptps(paddr_t); 405f5df1827Smickey 4063a36161cSart void pagezero(vaddr_t); 4073a36161cSart 408aea267e5Sdv void pmap_convert(struct pmap *, int); 409b767b017Sguenther void pmap_enter_special(vaddr_t, paddr_t, vm_prot_t); 4104034e82eSkettenis vaddr_t pmap_set_pml4_early(paddr_t pa); 4114034e82eSkettenis void pmap_clear_pml4_early(void); 41263567820Smlarkin 4132bd69a47Soga /* 4142bd69a47Soga * functions for flushing the cache for vaddrs and pages. 4152bd69a47Soga * these functions are not part of the MI pmap interface and thus 4162bd69a47Soga * should not be used as such. 4172bd69a47Soga */ 4182bd69a47Soga void pmap_flush_cache(vaddr_t, vsize_t); 4192bd69a47Soga #define pmap_flush_page(paddr) do { \ 4202bd69a47Soga KDASSERT(PHYS_TO_VM_PAGE(paddr) != NULL); \ 4212bd69a47Soga pmap_flush_cache(PMAP_DIRECT_MAP(paddr), PAGE_SIZE); \ 4222bd69a47Soga } while (/* CONSTCOND */ 0) 4232bd69a47Soga 424d62ebcb2Sderaadt #define PMAP_CHECK_COPYIN (pg_xo == 0) 425d62ebcb2Sderaadt 426e495a5daSart #define PMAP_STEAL_MEMORY /* enable pmap_steal_memory() */ 427f5df1827Smickey #define PMAP_GROWKERNEL /* turn on pmap_growkernel interface */ 428f5df1827Smickey 429f5df1827Smickey /* 430f5df1827Smickey * inline functions 431f5df1827Smickey */ 432f5df1827Smickey 433484ac2f4Sguenther static inline void 434f5df1827Smickey pmap_remove_all(struct pmap *pmap) 435f5df1827Smickey { 436f5df1827Smickey /* Nothing. */ 437f5df1827Smickey } 438f5df1827Smickey 439f5df1827Smickey /* 440f5df1827Smickey * pmap_update_pg: flush one page from the TLB (or flush the whole thing 441f5df1827Smickey * if hardware doesn't support one-page flushing) 442f5df1827Smickey */ 443f5df1827Smickey 444c50e9b22Sjsg static inline void 44500538108Sjsg pmap_update_pg(vaddr_t va) 446f5df1827Smickey { 447f5df1827Smickey invlpg(va); 448f5df1827Smickey } 449f5df1827Smickey 450f5df1827Smickey /* 451f5df1827Smickey * pmap_page_protect: change the protection of all recorded mappings 452f5df1827Smickey * of a managed page 453f5df1827Smickey * 454f5df1827Smickey * => this function is a frontend for pmap_page_remove/pmap_clear_attrs 455f5df1827Smickey * => we only have to worry about making the page more protected. 456f5df1827Smickey * unprotecting a page is done on-demand at fault time. 457f5df1827Smickey */ 458f5df1827Smickey 459c50e9b22Sjsg static inline void 460f5df1827Smickey pmap_page_protect(struct vm_page *pg, vm_prot_t prot) 461f5df1827Smickey { 46201852f87Skettenis if (prot == PROT_READ) { 463f5df1827Smickey (void) pmap_clear_attrs(pg, PG_RW); 464f5df1827Smickey } else { 46501852f87Skettenis KASSERT(prot == PROT_NONE); 466f5df1827Smickey pmap_page_remove(pg); 467f5df1827Smickey } 468f5df1827Smickey } 469f5df1827Smickey 470f5df1827Smickey /* 471f5df1827Smickey * pmap_protect: change the protection of pages in a pmap 472f5df1827Smickey * 473f5df1827Smickey * => this function is a frontend for pmap_remove/pmap_write_protect 474f5df1827Smickey * => we only have to worry about making the page more protected. 475f5df1827Smickey * unprotecting a page is done on-demand at fault time. 476f5df1827Smickey */ 477f5df1827Smickey 478c50e9b22Sjsg static inline void 47900538108Sjsg pmap_protect(struct pmap *pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot) 480f5df1827Smickey { 4811a48cf17Skettenis if (prot != PROT_NONE) { 482f5df1827Smickey pmap_write_protect(pmap, sva, eva, prot); 483f5df1827Smickey } else { 484f5df1827Smickey pmap_remove(pmap, sva, eva); 485f5df1827Smickey } 486f5df1827Smickey } 487f5df1827Smickey 488f5df1827Smickey /* 489f5df1827Smickey * various address inlines 490f5df1827Smickey * 491f5df1827Smickey * vtopte: return a pointer to the PTE mapping a VA, works only for 492f5df1827Smickey * user and PT addresses 493f5df1827Smickey * 494f5df1827Smickey * kvtopte: return a pointer to the PTE mapping a kernel VA 495f5df1827Smickey */ 496f5df1827Smickey 497484ac2f4Sguenther static inline pt_entry_t * 498f5df1827Smickey vtopte(vaddr_t va) 499f5df1827Smickey { 500f5df1827Smickey return (PTE_BASE + pl1_i(va)); 501f5df1827Smickey } 502f5df1827Smickey 503484ac2f4Sguenther static inline pt_entry_t * 504f5df1827Smickey kvtopte(vaddr_t va) 505f5df1827Smickey { 506f5df1827Smickey #ifdef LARGEPAGES 507f5df1827Smickey { 508f5df1827Smickey pd_entry_t *pde; 509f5df1827Smickey 510f5df1827Smickey pde = L1_BASE + pl2_i(va); 511f5df1827Smickey if (*pde & PG_PS) 512f5df1827Smickey return ((pt_entry_t *)pde); 513f5df1827Smickey } 514f5df1827Smickey #endif 515f5df1827Smickey 516f5df1827Smickey return (PTE_BASE + pl1_i(va)); 517f5df1827Smickey } 518f5df1827Smickey 519025e5398Sguenther #define PMAP_DIRECT_MAP(pa) ((vaddr_t)PMAP_DIRECT_BASE + (pa)) 520025e5398Sguenther #define PMAP_DIRECT_UNMAP(va) ((paddr_t)(va) - PMAP_DIRECT_BASE) 521643c2defSjason #define pmap_map_direct(pg) PMAP_DIRECT_MAP(VM_PAGE_TO_PHYS(pg)) 522643c2defSjason #define pmap_unmap_direct(va) PHYS_TO_VM_PAGE(PMAP_DIRECT_UNMAP(va)) 5233a36161cSart 5244814b8ceSart #define __HAVE_PMAP_DIRECT 52543687ba5Sguenther #define __HAVE_PMAP_MPSAFE_ENTER_COW 5264814b8ceSart 527f5df1827Smickey #endif /* _KERNEL && !_LOCORE */ 52862fe2d4bSmiod 52962fe2d4bSmiod #ifndef _LOCORE 53062fe2d4bSmiod struct pv_entry; 53162fe2d4bSmiod struct vm_page_md { 5320c33c81eSkettenis struct mutex pv_mtx; 53362fe2d4bSmiod struct pv_entry *pv_list; 53462fe2d4bSmiod }; 53562fe2d4bSmiod 53662fe2d4bSmiod #define VM_MDPAGE_INIT(pg) do { \ 5370c33c81eSkettenis mtx_init(&(pg)->mdpage.pv_mtx, IPL_VM); \ 53862fe2d4bSmiod (pg)->mdpage.pv_list = NULL; \ 53962fe2d4bSmiod } while (0) 54062fe2d4bSmiod #endif /* !_LOCORE */ 54162fe2d4bSmiod 5422fa72412Spirofti #endif /* _MACHINE_PMAP_H_ */ 543