Deleted Added
full compact
pmap.c (351449) pmap.c (354651)
1/*-
2 * Copyright (c) 1991 Regents of the University of California.
3 * All rights reserved.
4 * Copyright (c) 1994 John S. Dyson
5 * All rights reserved.
6 * Copyright (c) 1994 David Greenman
7 * All rights reserved.
8 * Copyright (c) 2003 Peter Wemm

--- 71 unchanged lines hidden (view full) ---

80 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
81 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
82 * SUCH DAMAGE.
83 */
84
85#define AMD64_NPT_AWARE
86
87#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1991 Regents of the University of California.
3 * All rights reserved.
4 * Copyright (c) 1994 John S. Dyson
5 * All rights reserved.
6 * Copyright (c) 1994 David Greenman
7 * All rights reserved.
8 * Copyright (c) 2003 Peter Wemm

--- 71 unchanged lines hidden (view full) ---

80 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
81 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
82 * SUCH DAMAGE.
83 */
84
85#define AMD64_NPT_AWARE
86
87#include <sys/cdefs.h>
88__FBSDID("$FreeBSD: stable/11/sys/amd64/amd64/pmap.c 351449 2019-08-24 00:35:59Z jhb $");
88__FBSDID("$FreeBSD: stable/11/sys/amd64/amd64/pmap.c 354651 2019-11-12 18:04:28Z kib $");
89
90/*
91 * Manages physical address maps.
92 *
93 * Since the information managed by this module is
94 * also stored by the logical address mapping module,
95 * this module may throw away valid virtual-to-physical
96 * mappings at almost any time. However, invalidations

--- 1124 unchanged lines hidden (view full) ---

1221void
1222pmap_page_init(vm_page_t m)
1223{
1224
1225 TAILQ_INIT(&m->md.pv_list);
1226 m->md.pat_mode = PAT_WRITE_BACK;
1227}
1228
89
90/*
91 * Manages physical address maps.
92 *
93 * Since the information managed by this module is
94 * also stored by the logical address mapping module,
95 * this module may throw away valid virtual-to-physical
96 * mappings at almost any time. However, invalidations

--- 1124 unchanged lines hidden (view full) ---

1221void
1222pmap_page_init(vm_page_t m)
1223{
1224
1225 TAILQ_INIT(&m->md.pv_list);
1226 m->md.pat_mode = PAT_WRITE_BACK;
1227}
1228
1229static int pmap_allow_2m_x_ept;
1230SYSCTL_INT(_vm_pmap, OID_AUTO, allow_2m_x_ept, CTLFLAG_RWTUN | CTLFLAG_NOFETCH,
1231 &pmap_allow_2m_x_ept, 0,
1232 "Allow executable superpage mappings in EPT");
1233
1234void
1235pmap_allow_2m_x_ept_recalculate(void)
1236{
1237 /*
1238 * SKL002, SKL012S. Since the EPT format is only used by
1239 * Intel CPUs, the vendor check is merely a formality.
1240 */
1241 if (!(cpu_vendor_id != CPU_VENDOR_INTEL ||
1242 (cpu_ia32_arch_caps & IA32_ARCH_CAP_IF_PSCHANGE_MC_NO) != 0 ||
1243 (CPUID_TO_FAMILY(cpu_id) == 0x6 &&
1244 (CPUID_TO_MODEL(cpu_id) == 0x26 || /* Atoms */
1245 CPUID_TO_MODEL(cpu_id) == 0x27 ||
1246 CPUID_TO_MODEL(cpu_id) == 0x35 ||
1247 CPUID_TO_MODEL(cpu_id) == 0x36 ||
1248 CPUID_TO_MODEL(cpu_id) == 0x37 ||
1249 CPUID_TO_MODEL(cpu_id) == 0x86 ||
1250 CPUID_TO_MODEL(cpu_id) == 0x1c ||
1251 CPUID_TO_MODEL(cpu_id) == 0x4a ||
1252 CPUID_TO_MODEL(cpu_id) == 0x4c ||
1253 CPUID_TO_MODEL(cpu_id) == 0x4d ||
1254 CPUID_TO_MODEL(cpu_id) == 0x5a ||
1255 CPUID_TO_MODEL(cpu_id) == 0x5c ||
1256 CPUID_TO_MODEL(cpu_id) == 0x5d ||
1257 CPUID_TO_MODEL(cpu_id) == 0x5f ||
1258 CPUID_TO_MODEL(cpu_id) == 0x6e ||
1259 CPUID_TO_MODEL(cpu_id) == 0x7a ||
1260 CPUID_TO_MODEL(cpu_id) == 0x57 || /* Knights */
1261 CPUID_TO_MODEL(cpu_id) == 0x85))))
1262 pmap_allow_2m_x_ept = 1;
1263 TUNABLE_INT_FETCH("hw.allow_2m_x_ept", &pmap_allow_2m_x_ept);
1264}
1265
1266static bool
1267pmap_allow_2m_x_page(pmap_t pmap, bool executable)
1268{
1269
1270 return (pmap->pm_type != PT_EPT || !executable ||
1271 !pmap_allow_2m_x_ept);
1272}
1273
1229/*
1230 * Initialize the pmap module.
1231 * Called by vm_init, to initialize any structures that the pmap
1232 * system needs to map virtual memory.
1233 */
1234void
1235pmap_init(void)
1236{

--- 28 unchanged lines hidden (view full) ---

1265 ptoa(i), FALSE);
1266 if (!ret && bootverbose)
1267 printf("page at %#lx already used\n",
1268 0x40000000 + ptoa(i));
1269 }
1270 }
1271 }
1272
1274/*
1275 * Initialize the pmap module.
1276 * Called by vm_init, to initialize any structures that the pmap
1277 * system needs to map virtual memory.
1278 */
1279void
1280pmap_init(void)
1281{

--- 28 unchanged lines hidden (view full) ---

1310 ptoa(i), FALSE);
1311 if (!ret && bootverbose)
1312 printf("page at %#lx already used\n",
1313 0x40000000 + ptoa(i));
1314 }
1315 }
1316 }
1317
1318 /* IFU */
1319 pmap_allow_2m_x_ept_recalculate();
1320
1273 /*
1274 * Initialize the vm page array entries for the kernel pmap's
1275 * page table pages.
1276 */
1277 PMAP_LOCK(kernel_pmap);
1278 for (i = 0; i < nkpt; i++) {
1279 mpte = PHYS_TO_VM_PAGE(KPTphys + (i << PAGE_SHIFT));
1280 KASSERT(mpte >= vm_page_array &&

--- 3264 unchanged lines hidden (view full) ---

4545 }
4546 }
4547 if (anychanged)
4548 pmap_invalidate_all(pmap);
4549 PMAP_UNLOCK(pmap);
4550}
4551
4552#if VM_NRESERVLEVEL > 0
1321 /*
1322 * Initialize the vm page array entries for the kernel pmap's
1323 * page table pages.
1324 */
1325 PMAP_LOCK(kernel_pmap);
1326 for (i = 0; i < nkpt; i++) {
1327 mpte = PHYS_TO_VM_PAGE(KPTphys + (i << PAGE_SHIFT));
1328 KASSERT(mpte >= vm_page_array &&

--- 3264 unchanged lines hidden (view full) ---

4593 }
4594 }
4595 if (anychanged)
4596 pmap_invalidate_all(pmap);
4597 PMAP_UNLOCK(pmap);
4598}
4599
4600#if VM_NRESERVLEVEL > 0
4601static bool
4602pmap_pde_ept_executable(pmap_t pmap, pd_entry_t pde)
4603{
4604
4605 if (pmap->pm_type != PT_EPT)
4606 return (false);
4607 return ((pde & EPT_PG_EXECUTE) != 0);
4608}
4609
4553/*
4554 * Tries to promote the 512, contiguous 4KB page mappings that are within a
4555 * single page table page (PTP) to a single 2MB page mapping. For promotion
4556 * to occur, two conditions must be met: (1) the 4KB page mappings must map
4557 * aligned, contiguous physical memory and (2) the 4KB page mappings must have
4558 * identical characteristics.
4559 */
4560static void

--- 18 unchanged lines hidden (view full) ---

4579 /*
4580 * Examine the first PTE in the specified PTP. Abort if this PTE is
4581 * either invalid, unused, or does not map the first 4KB physical page
4582 * within a 2MB page.
4583 */
4584 firstpte = (pt_entry_t *)PHYS_TO_DMAP(*pde & PG_FRAME);
4585setpde:
4586 newpde = *firstpte;
4610/*
4611 * Tries to promote the 512, contiguous 4KB page mappings that are within a
4612 * single page table page (PTP) to a single 2MB page mapping. For promotion
4613 * to occur, two conditions must be met: (1) the 4KB page mappings must map
4614 * aligned, contiguous physical memory and (2) the 4KB page mappings must have
4615 * identical characteristics.
4616 */
4617static void

--- 18 unchanged lines hidden (view full) ---

4636 /*
4637 * Examine the first PTE in the specified PTP. Abort if this PTE is
4638 * either invalid, unused, or does not map the first 4KB physical page
4639 * within a 2MB page.
4640 */
4641 firstpte = (pt_entry_t *)PHYS_TO_DMAP(*pde & PG_FRAME);
4642setpde:
4643 newpde = *firstpte;
4587 if ((newpde & ((PG_FRAME & PDRMASK) | PG_A | PG_V)) != (PG_A | PG_V)) {
4644 if ((newpde & ((PG_FRAME & PDRMASK) | PG_A | PG_V)) != (PG_A | PG_V) ||
4645 !pmap_allow_2m_x_page(pmap, pmap_pde_ept_executable(pmap,
4646 newpde))) {
4588 atomic_add_long(&pmap_pde_p_failures, 1);
4589 CTR2(KTR_PMAP, "pmap_promote_pde: failure for va %#lx"
4590 " in pmap %p", va, pmap);
4591 return;
4592 }
4593 if ((newpde & (PG_M | PG_RW)) == PG_RW) {
4594 /*
4595 * When PG_M is already clear, PG_RW can be cleared without

--- 409 unchanged lines hidden (view full) ---

5005
5006 PG_G = pmap_global_bit(pmap);
5007 PG_RW = pmap_rw_bit(pmap);
5008 KASSERT((newpde & (pmap_modified_bit(pmap) | PG_RW)) != PG_RW,
5009 ("pmap_enter_pde: newpde is missing PG_M"));
5010 PG_V = pmap_valid_bit(pmap);
5011 PMAP_LOCK_ASSERT(pmap, MA_OWNED);
5012
4647 atomic_add_long(&pmap_pde_p_failures, 1);
4648 CTR2(KTR_PMAP, "pmap_promote_pde: failure for va %#lx"
4649 " in pmap %p", va, pmap);
4650 return;
4651 }
4652 if ((newpde & (PG_M | PG_RW)) == PG_RW) {
4653 /*
4654 * When PG_M is already clear, PG_RW can be cleared without

--- 409 unchanged lines hidden (view full) ---

5064
5065 PG_G = pmap_global_bit(pmap);
5066 PG_RW = pmap_rw_bit(pmap);
5067 KASSERT((newpde & (pmap_modified_bit(pmap) | PG_RW)) != PG_RW,
5068 ("pmap_enter_pde: newpde is missing PG_M"));
5069 PG_V = pmap_valid_bit(pmap);
5070 PMAP_LOCK_ASSERT(pmap, MA_OWNED);
5071
5072 if (!pmap_allow_2m_x_page(pmap, pmap_pde_ept_executable(pmap,
5073 newpde))) {
5074 CTR2(KTR_PMAP, "pmap_enter_pde: 2m x blocked for va %#lx"
5075 " in pmap %p", va, pmap);
5076 return (KERN_FAILURE);
5077 }
5013 if ((pdpg = pmap_allocpde(pmap, va, (flags & PMAP_ENTER_NOSLEEP) != 0 ?
5014 NULL : lockp)) == NULL) {
5015 CTR2(KTR_PMAP, "pmap_enter_pde: failure for va %#lx"
5016 " in pmap %p", va, pmap);
5017 return (KERN_RESOURCE_SHORTAGE);
5018 }
5019 pde = (pd_entry_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(pdpg));
5020 pde = &pde[pmap_pde_index(va)];

--- 113 unchanged lines hidden (view full) ---

5134 mpte = NULL;
5135 m = m_start;
5136 lock = NULL;
5137 PMAP_LOCK(pmap);
5138 while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
5139 va = start + ptoa(diff);
5140 if ((va & PDRMASK) == 0 && va + NBPDR <= end &&
5141 m->psind == 1 && pmap_ps_enabled(pmap) &&
5078 if ((pdpg = pmap_allocpde(pmap, va, (flags & PMAP_ENTER_NOSLEEP) != 0 ?
5079 NULL : lockp)) == NULL) {
5080 CTR2(KTR_PMAP, "pmap_enter_pde: failure for va %#lx"
5081 " in pmap %p", va, pmap);
5082 return (KERN_RESOURCE_SHORTAGE);
5083 }
5084 pde = (pd_entry_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(pdpg));
5085 pde = &pde[pmap_pde_index(va)];

--- 113 unchanged lines hidden (view full) ---

5199 mpte = NULL;
5200 m = m_start;
5201 lock = NULL;
5202 PMAP_LOCK(pmap);
5203 while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
5204 va = start + ptoa(diff);
5205 if ((va & PDRMASK) == 0 && va + NBPDR <= end &&
5206 m->psind == 1 && pmap_ps_enabled(pmap) &&
5207 pmap_allow_2m_x_page(pmap, (prot & VM_PROT_EXECUTE) != 0) &&
5142 pmap_enter_2mpage(pmap, va, m, prot, &lock))
5143 m = &m[NBPDR / PAGE_SIZE - 1];
5144 else
5145 mpte = pmap_enter_quick_locked(pmap, va, m, prot,
5146 mpte, &lock);
5147 m = TAILQ_NEXT(m, listq);
5148 }
5149 if (lock != NULL)

--- 3072 unchanged lines hidden ---
5208 pmap_enter_2mpage(pmap, va, m, prot, &lock))
5209 m = &m[NBPDR / PAGE_SIZE - 1];
5210 else
5211 mpte = pmap_enter_quick_locked(pmap, va, m, prot,
5212 mpte, &lock);
5213 m = TAILQ_NEXT(m, listq);
5214 }
5215 if (lock != NULL)

--- 3072 unchanged lines hidden ---