* 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,
| 7992 | * that eventual TLB invalidation. |
| 7993 | */ |
| 7994 | void |
| 7995 | pmap_remove_pages(pmap_t pmap) |
| 7996 | { |
| 7997 | pd_entry_t ptepde; |
| 7998 | pt_entry_t *pte, tpte; |
| 7999 | pt_entry_t PG_M, PG_RW, PG_V; |
| 8000 | struct spglist free; |
| 8001 | struct pv_chunklist free_chunks[PMAP_MEMDOM]; |
| 8002 | vm_page_t m, mpte, mt; |
| 8003 | pv_entry_t pv; |
| 8004 | struct md_page *pvh; |
| 8005 | struct pv_chunk *pc, *npc; |
| 8006 | struct rwlock *lock; |
| 8007 | int64_t bit; |
| 8008 | uint64_t inuse, bitmask; |
| 8009 | int allfree, field, freed, i, idx; |
| 8010 | boolean_t superpage; |
| 8011 | vm_paddr_t pa; |
| 8012 | |
| 8013 | /* |
| 8014 | * Assert that the given pmap is only active on the current |
| 8015 | * CPU. Unfortunately, we cannot block another CPU from |
| 8016 | * activating the pmap while this function is executing. |
| 8017 | */ |
| 8018 | KASSERT(pmap == PCPU_GET(curpmap), ("non-current pmap %p", pmap)); |
| 8019 | #ifdef INVARIANTS |
| 8020 | { |
| 8021 | cpuset_t other_cpus; |
| 8022 | |
| 8023 | other_cpus = all_cpus; |
| 8024 | critical_enter(); |
| 8025 | CPU_CLR(PCPU_GET(cpuid), &other_cpus); |
| 8026 | CPU_AND(&other_cpus, &pmap->pm_active); |
| 8027 | critical_exit(); |
| 8028 | KASSERT(CPU_EMPTY(&other_cpus), ("pmap active %p", pmap)); |
| 8029 | } |
| 8030 | #endif |
| 8031 | |
| 8032 | lock = NULL; |
| 8033 | PG_M = pmap_modified_bit(pmap); |
| 8034 | PG_V = pmap_valid_bit(pmap); |
| 8035 | PG_RW = pmap_rw_bit(pmap); |
| 8036 | |
| 8037 | for (i = 0; i < PMAP_MEMDOM; i++) |
| 8038 | TAILQ_INIT(&free_chunks[i]); |
| 8039 | SLIST_INIT(&free); |
| 8040 | PMAP_LOCK(pmap); |
| 8041 | TAILQ_FOREACH_SAFE(pc, &pmap->pm_pvchunk, pc_list, npc) { |
| 8042 | allfree = 1; |
| 8043 | freed = 0; |
| 8044 | for (field = 0; field < _NPCM; field++) { |
| 8045 | inuse = ~pc->pc_map[field] & pc_freemask[field]; |
| 8046 | while (inuse != 0) { |
| 8047 | bit = bsfq(inuse); |
| 8048 | bitmask = 1UL << bit; |
| 8049 | idx = field * 64 + bit; |
| 8050 | pv = &pc->pc_pventry[idx]; |
| 8051 | inuse &= ~bitmask; |
nothing calls this directly
no test coverage detected