MCPcopy Create free account
hub / github.com/F-Stack/f-stack / pmap_enter_pde

Function pmap_enter_pde

freebsd/amd64/amd64/pmap.c:7058–7190  ·  view source on GitHub ↗

* Tries to create the specified 2MB page mapping. Returns KERN_SUCCESS if * the mapping was created, and either KERN_FAILURE or KERN_RESOURCE_SHORTAGE * otherwise. Returns KERN_FAILURE if PMAP_ENTER_NOREPLACE was specified and * a mapping already exists at the specified virtual address. Returns * KERN_RESOURCE_SHORTAGE if PMAP_ENTER_NOSLEEP was specified and a page table * page allocation

Source from the content-addressed store, hash-verified

7056 * The parameter "m" is only used when creating a managed, writeable mapping.
7057 */
7058static int
7059pmap_enter_pde(pmap_t pmap, vm_offset_t va, pd_entry_t newpde, u_int flags,
7060 vm_page_t m, struct rwlock **lockp)
7061{
7062 struct spglist free;
7063 pd_entry_t oldpde, *pde;
7064 pt_entry_t PG_G, PG_RW, PG_V;
7065 vm_page_t mt, pdpg;
7066
7067 KASSERT(pmap == kernel_pmap || (newpde & PG_W) == 0,
7068 ("pmap_enter_pde: cannot create wired user mapping"));
7069 PG_G = pmap_global_bit(pmap);
7070 PG_RW = pmap_rw_bit(pmap);
7071 KASSERT((newpde & (pmap_modified_bit(pmap) | PG_RW)) != PG_RW,
7072 ("pmap_enter_pde: newpde is missing PG_M"));
7073 PG_V = pmap_valid_bit(pmap);
7074 PMAP_LOCK_ASSERT(pmap, MA_OWNED);
7075
7076 if (!pmap_allow_2m_x_page(pmap, pmap_pde_ept_executable(pmap,
7077 newpde))) {
7078 CTR2(KTR_PMAP, "pmap_enter_pde: 2m x blocked for va %#lx"
7079 " in pmap %p", va, pmap);
7080 return (KERN_FAILURE);
7081 }
7082 if ((pde = pmap_alloc_pde(pmap, va, &pdpg, (flags &
7083 PMAP_ENTER_NOSLEEP) != 0 ? NULL : lockp)) == NULL) {
7084 CTR2(KTR_PMAP, "pmap_enter_pde: failure for va %#lx"
7085 " in pmap %p", va, pmap);
7086 return (KERN_RESOURCE_SHORTAGE);
7087 }
7088
7089 /*
7090 * If pkru is not same for the whole pde range, return failure
7091 * and let vm_fault() cope. Check after pde allocation, since
7092 * it could sleep.
7093 */
7094 if (!pmap_pkru_same(pmap, va, va + NBPDR)) {
7095 pmap_abort_ptp(pmap, va, pdpg);
7096 return (KERN_FAILURE);
7097 }
7098 if (va < VM_MAXUSER_ADDRESS && pmap->pm_type == PT_X86) {
7099 newpde &= ~X86_PG_PKU_MASK;
7100 newpde |= pmap_pkru_get(pmap, va);
7101 }
7102
7103 /*
7104 * If there are existing mappings, either abort or remove them.
7105 */
7106 oldpde = *pde;
7107 if ((oldpde & PG_V) != 0) {
7108 KASSERT(pdpg == NULL || pdpg->ref_count > 1,
7109 ("pmap_enter_pde: pdpg's reference count is too low"));
7110 if ((flags & PMAP_ENTER_NOREPLACE) != 0 && (va <
7111 VM_MAXUSER_ADDRESS || (oldpde & PG_PS) != 0 ||
7112 !pmap_every_pte_zero(oldpde & PG_FRAME))) {
7113 if (pdpg != NULL)
7114 pdpg->ref_count--;
7115 CTR2(KTR_PMAP, "pmap_enter_pde: failure for va %#lx"

Callers 2

pmap_enterFunction · 0.70
pmap_enter_2mpageFunction · 0.70

Calls 15

pmap_global_bitFunction · 0.85
pmap_rw_bitFunction · 0.85
pmap_modified_bitFunction · 0.85
pmap_valid_bitFunction · 0.85
pmap_allow_2m_x_pageFunction · 0.85
pmap_pde_ept_executableFunction · 0.85
pmap_alloc_pdeFunction · 0.85
pmap_pkru_sameFunction · 0.85
pmap_pkru_getFunction · 0.85
vm_page_free_pages_toqFunction · 0.85
PHYS_TO_VM_PAGEFunction · 0.85
vm_page_aflag_setFunction · 0.85

Tested by

no test coverage detected