* Tries to demote a 1GB page mapping. */
| 9051 | * Tries to demote a 1GB page mapping. |
| 9052 | */ |
| 9053 | static boolean_t |
| 9054 | pmap_demote_pdpe(pmap_t pmap, pdp_entry_t *pdpe, vm_offset_t va) |
| 9055 | { |
| 9056 | pdp_entry_t newpdpe, oldpdpe; |
| 9057 | pd_entry_t *firstpde, newpde, *pde; |
| 9058 | pt_entry_t PG_A, PG_M, PG_RW, PG_V; |
| 9059 | vm_paddr_t pdpgpa; |
| 9060 | vm_page_t pdpg; |
| 9061 | |
| 9062 | PG_A = pmap_accessed_bit(pmap); |
| 9063 | PG_M = pmap_modified_bit(pmap); |
| 9064 | PG_V = pmap_valid_bit(pmap); |
| 9065 | PG_RW = pmap_rw_bit(pmap); |
| 9066 | |
| 9067 | PMAP_LOCK_ASSERT(pmap, MA_OWNED); |
| 9068 | oldpdpe = *pdpe; |
| 9069 | KASSERT((oldpdpe & (PG_PS | PG_V)) == (PG_PS | PG_V), |
| 9070 | ("pmap_demote_pdpe: oldpdpe is missing PG_PS and/or PG_V")); |
| 9071 | if ((pdpg = vm_page_alloc(NULL, va >> PDPSHIFT, VM_ALLOC_INTERRUPT | |
| 9072 | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED)) == NULL) { |
| 9073 | CTR2(KTR_PMAP, "pmap_demote_pdpe: failure for va %#lx" |
| 9074 | " in pmap %p", va, pmap); |
| 9075 | return (FALSE); |
| 9076 | } |
| 9077 | pdpgpa = VM_PAGE_TO_PHYS(pdpg); |
| 9078 | firstpde = (pd_entry_t *)PHYS_TO_DMAP(pdpgpa); |
| 9079 | newpdpe = pdpgpa | PG_M | PG_A | (oldpdpe & PG_U) | PG_RW | PG_V; |
| 9080 | KASSERT((oldpdpe & PG_A) != 0, |
| 9081 | ("pmap_demote_pdpe: oldpdpe is missing PG_A")); |
| 9082 | KASSERT((oldpdpe & (PG_M | PG_RW)) != PG_RW, |
| 9083 | ("pmap_demote_pdpe: oldpdpe is missing PG_M")); |
| 9084 | newpde = oldpdpe; |
| 9085 | |
| 9086 | /* |
| 9087 | * Initialize the page directory page. |
| 9088 | */ |
| 9089 | for (pde = firstpde; pde < firstpde + NPDEPG; pde++) { |
| 9090 | *pde = newpde; |
| 9091 | newpde += NBPDR; |
| 9092 | } |
| 9093 | |
| 9094 | /* |
| 9095 | * Demote the mapping. |
| 9096 | */ |
| 9097 | *pdpe = newpdpe; |
| 9098 | |
| 9099 | /* |
| 9100 | * Invalidate a stale recursive mapping of the page directory page. |
| 9101 | */ |
| 9102 | pmap_invalidate_page(pmap, (vm_offset_t)vtopde(va)); |
| 9103 | |
| 9104 | pmap_pdpe_demotions++; |
| 9105 | CTR2(KTR_PMAP, "pmap_demote_pdpe: success for va %#lx" |
| 9106 | " in pmap %p", va, pmap); |
| 9107 | return (TRUE); |
| 9108 | } |
| 9109 | |
| 9110 | /* |
no test coverage detected