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

Function pmap_enter_l2

freebsd/arm64/arm64/pmap.c:4268–4364  ·  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

4266 * The parameter "m" is only used when creating a managed, writeable mapping.
4267 */
4268static int
4269pmap_enter_l2(pmap_t pmap, vm_offset_t va, pd_entry_t new_l2, u_int flags,
4270 vm_page_t m, struct rwlock **lockp)
4271{
4272 struct spglist free;
4273 pd_entry_t *l2, old_l2;
4274 vm_page_t l2pg, mt;
4275
4276 PMAP_LOCK_ASSERT(pmap, MA_OWNED);
4277
4278 if ((l2 = pmap_alloc_l2(pmap, va, &l2pg, (flags &
4279 PMAP_ENTER_NOSLEEP) != 0 ? NULL : lockp)) == NULL) {
4280 CTR2(KTR_PMAP, "pmap_enter_l2: failure for va %#lx in pmap %p",
4281 va, pmap);
4282 return (KERN_RESOURCE_SHORTAGE);
4283 }
4284
4285 /*
4286 * If there are existing mappings, either abort or remove them.
4287 */
4288 if ((old_l2 = pmap_load(l2)) != 0) {
4289 KASSERT(l2pg == NULL || l2pg->ref_count > 1,
4290 ("pmap_enter_l2: l2pg's ref count is too low"));
4291 if ((flags & PMAP_ENTER_NOREPLACE) != 0 && (va <
4292 VM_MAXUSER_ADDRESS || (old_l2 & ATTR_DESCR_MASK) ==
4293 L2_BLOCK || !pmap_every_pte_zero(old_l2 & ~ATTR_MASK))) {
4294 if (l2pg != NULL)
4295 l2pg->ref_count--;
4296 CTR2(KTR_PMAP, "pmap_enter_l2: failure for va %#lx"
4297 " in pmap %p", va, pmap);
4298 return (KERN_FAILURE);
4299 }
4300 SLIST_INIT(&free);
4301 if ((old_l2 & ATTR_DESCR_MASK) == L2_BLOCK)
4302 (void)pmap_remove_l2(pmap, l2, va,
4303 pmap_load(pmap_l1(pmap, va)), &free, lockp);
4304 else
4305 pmap_remove_l3_range(pmap, old_l2, va, va + L2_SIZE,
4306 &free, lockp);
4307 if (va < VM_MAXUSER_ADDRESS) {
4308 vm_page_free_pages_toq(&free, true);
4309 KASSERT(pmap_load(l2) == 0,
4310 ("pmap_enter_l2: non-zero L2 entry %p", l2));
4311 } else {
4312 KASSERT(SLIST_EMPTY(&free),
4313 ("pmap_enter_l2: freed kernel page table page"));
4314
4315 /*
4316 * Both pmap_remove_l2() and pmap_remove_l3_range()
4317 * will leave the kernel page table page zero filled.
4318 * Nonetheless, the TLB could have an intermediate
4319 * entry for the kernel page table page.
4320 */
4321 mt = PHYS_TO_VM_PAGE(pmap_load(l2) & ~ATTR_MASK);
4322 if (pmap_insert_pt_page(pmap, mt, false))
4323 panic("pmap_enter_l2: trie insert failed");
4324 pmap_clear(l2);
4325 pmap_invalidate_page(pmap, va);

Callers 2

pmap_enterFunction · 0.85
pmap_enter_2mpageFunction · 0.85

Calls 14

pmap_alloc_l2Function · 0.85
pmap_remove_l2Function · 0.85
pmap_l1Function · 0.85
pmap_remove_l3_rangeFunction · 0.85
vm_page_free_pages_toqFunction · 0.85
PHYS_TO_VM_PAGEFunction · 0.85
pmap_pv_insert_l2Function · 0.85
vm_page_aflag_setFunction · 0.85
atomic_add_longFunction · 0.85
pmap_every_pte_zeroFunction · 0.70
pmap_insert_pt_pageFunction · 0.70
pmap_invalidate_pageFunction · 0.70

Tested by

no test coverage detected