* Destroy all managed, non-wired mappings in the given user-space * pmap. This pmap cannot be active on any processor besides the * caller. * * This function cannot be applied to the kernel pmap. Moreover, it * is not intended for general use. It is only to be used during * process termination. Consequently, it can be implemented in ways * that make it faster than pmap_remove(). First,
| 5085 | * this function starts. |
| 5086 | */ |
| 5087 | void |
| 5088 | pmap_remove_pages(pmap_t pmap) |
| 5089 | { |
| 5090 | pd_entry_t *pde; |
| 5091 | pt_entry_t *pte, tpte; |
| 5092 | struct spglist free; |
| 5093 | vm_page_t m, ml3, mt; |
| 5094 | pv_entry_t pv; |
| 5095 | struct md_page *pvh; |
| 5096 | struct pv_chunk *pc, *npc; |
| 5097 | struct rwlock *lock; |
| 5098 | int64_t bit; |
| 5099 | uint64_t inuse, bitmask; |
| 5100 | int allfree, field, freed, idx, lvl; |
| 5101 | vm_paddr_t pa; |
| 5102 | |
| 5103 | lock = NULL; |
| 5104 | |
| 5105 | SLIST_INIT(&free); |
| 5106 | PMAP_LOCK(pmap); |
| 5107 | TAILQ_FOREACH_SAFE(pc, &pmap->pm_pvchunk, pc_list, npc) { |
| 5108 | allfree = 1; |
| 5109 | freed = 0; |
| 5110 | for (field = 0; field < _NPCM; field++) { |
| 5111 | inuse = ~pc->pc_map[field] & pc_freemask[field]; |
| 5112 | while (inuse != 0) { |
| 5113 | bit = ffsl(inuse) - 1; |
| 5114 | bitmask = 1UL << bit; |
| 5115 | idx = field * 64 + bit; |
| 5116 | pv = &pc->pc_pventry[idx]; |
| 5117 | inuse &= ~bitmask; |
| 5118 | |
| 5119 | pde = pmap_pde(pmap, pv->pv_va, &lvl); |
| 5120 | KASSERT(pde != NULL, |
| 5121 | ("Attempting to remove an unmapped page")); |
| 5122 | |
| 5123 | switch(lvl) { |
| 5124 | case 1: |
| 5125 | pte = pmap_l1_to_l2(pde, pv->pv_va); |
| 5126 | tpte = pmap_load(pte); |
| 5127 | KASSERT((tpte & ATTR_DESCR_MASK) == |
| 5128 | L2_BLOCK, |
| 5129 | ("Attempting to remove an invalid " |
| 5130 | "block: %lx", tpte)); |
| 5131 | break; |
| 5132 | case 2: |
| 5133 | pte = pmap_l2_to_l3(pde, pv->pv_va); |
| 5134 | tpte = pmap_load(pte); |
| 5135 | KASSERT((tpte & ATTR_DESCR_MASK) == |
| 5136 | L3_PAGE, |
| 5137 | ("Attempting to remove an invalid " |
| 5138 | "page: %lx", tpte)); |
| 5139 | break; |
| 5140 | default: |
| 5141 | panic( |
| 5142 | "Invalid page directory level: %d", |
| 5143 | lvl); |
| 5144 | } |
nothing calls this directly
no test coverage detected