* Clear the write and modified bits in each of the given page's mappings. */
| 8324 | * Clear the write and modified bits in each of the given page's mappings. |
| 8325 | */ |
| 8326 | void |
| 8327 | pmap_remove_write(vm_page_t m) |
| 8328 | { |
| 8329 | struct md_page *pvh; |
| 8330 | pmap_t pmap; |
| 8331 | struct rwlock *lock; |
| 8332 | pv_entry_t next_pv, pv; |
| 8333 | pd_entry_t *pde; |
| 8334 | pt_entry_t oldpte, *pte, PG_M, PG_RW; |
| 8335 | vm_offset_t va; |
| 8336 | int pvh_gen, md_gen; |
| 8337 | |
| 8338 | KASSERT((m->oflags & VPO_UNMANAGED) == 0, |
| 8339 | ("pmap_remove_write: page %p is not managed", m)); |
| 8340 | |
| 8341 | vm_page_assert_busied(m); |
| 8342 | if (!pmap_page_is_write_mapped(m)) |
| 8343 | return; |
| 8344 | |
| 8345 | lock = VM_PAGE_TO_PV_LIST_LOCK(m); |
| 8346 | pvh = (m->flags & PG_FICTITIOUS) != 0 ? &pv_dummy : |
| 8347 | pa_to_pvh(VM_PAGE_TO_PHYS(m)); |
| 8348 | retry_pv_loop: |
| 8349 | rw_wlock(lock); |
| 8350 | TAILQ_FOREACH_SAFE(pv, &pvh->pv_list, pv_next, next_pv) { |
| 8351 | pmap = PV_PMAP(pv); |
| 8352 | if (!PMAP_TRYLOCK(pmap)) { |
| 8353 | pvh_gen = pvh->pv_gen; |
| 8354 | rw_wunlock(lock); |
| 8355 | PMAP_LOCK(pmap); |
| 8356 | rw_wlock(lock); |
| 8357 | if (pvh_gen != pvh->pv_gen) { |
| 8358 | PMAP_UNLOCK(pmap); |
| 8359 | rw_wunlock(lock); |
| 8360 | goto retry_pv_loop; |
| 8361 | } |
| 8362 | } |
| 8363 | PG_RW = pmap_rw_bit(pmap); |
| 8364 | va = pv->pv_va; |
| 8365 | pde = pmap_pde(pmap, va); |
| 8366 | if ((*pde & PG_RW) != 0) |
| 8367 | (void)pmap_demote_pde_locked(pmap, pde, va, &lock); |
| 8368 | KASSERT(lock == VM_PAGE_TO_PV_LIST_LOCK(m), |
| 8369 | ("inconsistent pv lock %p %p for page %p", |
| 8370 | lock, VM_PAGE_TO_PV_LIST_LOCK(m), m)); |
| 8371 | PMAP_UNLOCK(pmap); |
| 8372 | } |
| 8373 | TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) { |
| 8374 | pmap = PV_PMAP(pv); |
| 8375 | if (!PMAP_TRYLOCK(pmap)) { |
| 8376 | pvh_gen = pvh->pv_gen; |
| 8377 | md_gen = m->md.pv_gen; |
| 8378 | rw_wunlock(lock); |
| 8379 | PMAP_LOCK(pmap); |
| 8380 | rw_wlock(lock); |
| 8381 | if (pvh_gen != pvh->pv_gen || |
| 8382 | md_gen != m->md.pv_gen) { |
| 8383 | PMAP_UNLOCK(pmap); |
nothing calls this directly
no test coverage detected