| 3139 | */ |
| 3140 | |
| 3141 | void |
| 3142 | pmap_remove_all(vm_page_t m) |
| 3143 | { |
| 3144 | struct md_page *pvh; |
| 3145 | pv_entry_t pv; |
| 3146 | pmap_t pmap; |
| 3147 | struct rwlock *lock; |
| 3148 | pd_entry_t *pde, tpde; |
| 3149 | pt_entry_t *pte, tpte; |
| 3150 | vm_offset_t va; |
| 3151 | struct spglist free; |
| 3152 | int lvl, pvh_gen, md_gen; |
| 3153 | |
| 3154 | KASSERT((m->oflags & VPO_UNMANAGED) == 0, |
| 3155 | ("pmap_remove_all: page %p is not managed", m)); |
| 3156 | SLIST_INIT(&free); |
| 3157 | lock = VM_PAGE_TO_PV_LIST_LOCK(m); |
| 3158 | pvh = (m->flags & PG_FICTITIOUS) != 0 ? &pv_dummy : page_to_pvh(m); |
| 3159 | retry: |
| 3160 | rw_wlock(lock); |
| 3161 | while ((pv = TAILQ_FIRST(&pvh->pv_list)) != NULL) { |
| 3162 | pmap = PV_PMAP(pv); |
| 3163 | if (!PMAP_TRYLOCK(pmap)) { |
| 3164 | pvh_gen = pvh->pv_gen; |
| 3165 | rw_wunlock(lock); |
| 3166 | PMAP_LOCK(pmap); |
| 3167 | rw_wlock(lock); |
| 3168 | if (pvh_gen != pvh->pv_gen) { |
| 3169 | rw_wunlock(lock); |
| 3170 | PMAP_UNLOCK(pmap); |
| 3171 | goto retry; |
| 3172 | } |
| 3173 | } |
| 3174 | va = pv->pv_va; |
| 3175 | pte = pmap_pte(pmap, va, &lvl); |
| 3176 | KASSERT(pte != NULL, |
| 3177 | ("pmap_remove_all: no page table entry found")); |
| 3178 | KASSERT(lvl == 2, |
| 3179 | ("pmap_remove_all: invalid pte level %d", lvl)); |
| 3180 | |
| 3181 | pmap_demote_l2_locked(pmap, pte, va, &lock); |
| 3182 | PMAP_UNLOCK(pmap); |
| 3183 | } |
| 3184 | while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) { |
| 3185 | pmap = PV_PMAP(pv); |
| 3186 | PMAP_ASSERT_STAGE1(pmap); |
| 3187 | if (!PMAP_TRYLOCK(pmap)) { |
| 3188 | pvh_gen = pvh->pv_gen; |
| 3189 | md_gen = m->md.pv_gen; |
| 3190 | rw_wunlock(lock); |
| 3191 | PMAP_LOCK(pmap); |
| 3192 | rw_wlock(lock); |
| 3193 | if (pvh_gen != pvh->pv_gen || md_gen != m->md.pv_gen) { |
| 3194 | rw_wunlock(lock); |
| 3195 | PMAP_UNLOCK(pmap); |
| 3196 | goto retry; |
| 3197 | } |
| 3198 | } |
nothing calls this directly
no test coverage detected