* The ptepindexes, i.e. page indices, of the page table pages encountered * while translating virtual address va are defined as follows: * - for the page table page (last level), * ptepindex = pmap_pde_pindex(va) = va >> PDRSHIFT, * in other words, it is just the index of the PDE that maps the page * table page. * - for the page directory page, * ptepindex = NUPDE (number of u
| 4390 | * since it is statically allocated by pmap_pinit() and not by pmap_allocpte(). |
| 4391 | */ |
| 4392 | static vm_page_t |
| 4393 | pmap_allocpte_nosleep(pmap_t pmap, vm_pindex_t ptepindex, struct rwlock **lockp, |
| 4394 | vm_offset_t va) |
| 4395 | { |
| 4396 | vm_pindex_t pml5index, pml4index; |
| 4397 | pml5_entry_t *pml5, *pml5u; |
| 4398 | pml4_entry_t *pml4, *pml4u; |
| 4399 | pdp_entry_t *pdp; |
| 4400 | pd_entry_t *pd; |
| 4401 | vm_page_t m, pdpg; |
| 4402 | pt_entry_t PG_A, PG_M, PG_RW, PG_V; |
| 4403 | |
| 4404 | PMAP_LOCK_ASSERT(pmap, MA_OWNED); |
| 4405 | |
| 4406 | PG_A = pmap_accessed_bit(pmap); |
| 4407 | PG_M = pmap_modified_bit(pmap); |
| 4408 | PG_V = pmap_valid_bit(pmap); |
| 4409 | PG_RW = pmap_rw_bit(pmap); |
| 4410 | |
| 4411 | /* |
| 4412 | * Allocate a page table page. |
| 4413 | */ |
| 4414 | if ((m = vm_page_alloc(NULL, ptepindex, VM_ALLOC_NOOBJ | |
| 4415 | VM_ALLOC_WIRED | VM_ALLOC_ZERO)) == NULL) |
| 4416 | return (NULL); |
| 4417 | if ((m->flags & PG_ZERO) == 0) |
| 4418 | pmap_zero_page(m); |
| 4419 | |
| 4420 | /* |
| 4421 | * Map the pagetable page into the process address space, if |
| 4422 | * it isn't already there. |
| 4423 | */ |
| 4424 | if (ptepindex >= NUPDE + NUPDPE + NUPML4E) { |
| 4425 | MPASS(pmap_is_la57(pmap)); |
| 4426 | |
| 4427 | pml5index = pmap_pml5e_index(va); |
| 4428 | pml5 = &pmap->pm_pmltop[pml5index]; |
| 4429 | KASSERT((*pml5 & PG_V) == 0, |
| 4430 | ("pmap %p va %#lx pml5 %#lx", pmap, va, *pml5)); |
| 4431 | *pml5 = VM_PAGE_TO_PHYS(m) | PG_U | PG_RW | PG_V | PG_A | PG_M; |
| 4432 | |
| 4433 | if (pmap->pm_pmltopu != NULL && pml5index < NUPML5E) { |
| 4434 | if (pmap->pm_ucr3 != PMAP_NO_CR3) |
| 4435 | *pml5 |= pg_nx; |
| 4436 | |
| 4437 | pml5u = &pmap->pm_pmltopu[pml5index]; |
| 4438 | *pml5u = VM_PAGE_TO_PHYS(m) | PG_U | PG_RW | PG_V | |
| 4439 | PG_A | PG_M; |
| 4440 | } |
| 4441 | } else if (ptepindex >= NUPDE + NUPDPE) { |
| 4442 | pml4index = pmap_pml4e_index(va); |
| 4443 | /* Wire up a new PDPE page */ |
| 4444 | pml4 = pmap_allocpte_getpml4(pmap, lockp, va, true); |
| 4445 | if (pml4 == NULL) { |
| 4446 | vm_page_unwire_noq(m); |
| 4447 | vm_page_free_zero(m); |
| 4448 | return (NULL); |
| 4449 | } |
no test coverage detected