* Clear the write and modified bits in each of the given page's mappings. */
| 5404 | * Clear the write and modified bits in each of the given page's mappings. |
| 5405 | */ |
| 5406 | void |
| 5407 | pmap_remove_write(vm_page_t m) |
| 5408 | { |
| 5409 | struct md_page *pvh; |
| 5410 | pmap_t pmap; |
| 5411 | struct rwlock *lock; |
| 5412 | pv_entry_t next_pv, pv; |
| 5413 | pt_entry_t oldpte, *pte; |
| 5414 | vm_offset_t va; |
| 5415 | int lvl, md_gen, pvh_gen; |
| 5416 | |
| 5417 | KASSERT((m->oflags & VPO_UNMANAGED) == 0, |
| 5418 | ("pmap_remove_write: page %p is not managed", m)); |
| 5419 | vm_page_assert_busied(m); |
| 5420 | |
| 5421 | if (!pmap_page_is_write_mapped(m)) |
| 5422 | return; |
| 5423 | lock = VM_PAGE_TO_PV_LIST_LOCK(m); |
| 5424 | pvh = (m->flags & PG_FICTITIOUS) != 0 ? &pv_dummy : page_to_pvh(m); |
| 5425 | retry_pv_loop: |
| 5426 | rw_wlock(lock); |
| 5427 | TAILQ_FOREACH_SAFE(pv, &pvh->pv_list, pv_next, next_pv) { |
| 5428 | pmap = PV_PMAP(pv); |
| 5429 | PMAP_ASSERT_STAGE1(pmap); |
| 5430 | if (!PMAP_TRYLOCK(pmap)) { |
| 5431 | pvh_gen = pvh->pv_gen; |
| 5432 | rw_wunlock(lock); |
| 5433 | PMAP_LOCK(pmap); |
| 5434 | rw_wlock(lock); |
| 5435 | if (pvh_gen != pvh->pv_gen) { |
| 5436 | PMAP_UNLOCK(pmap); |
| 5437 | rw_wunlock(lock); |
| 5438 | goto retry_pv_loop; |
| 5439 | } |
| 5440 | } |
| 5441 | va = pv->pv_va; |
| 5442 | pte = pmap_pte(pmap, pv->pv_va, &lvl); |
| 5443 | if ((pmap_load(pte) & ATTR_SW_DBM) != 0) |
| 5444 | (void)pmap_demote_l2_locked(pmap, pte, va, &lock); |
| 5445 | KASSERT(lock == VM_PAGE_TO_PV_LIST_LOCK(m), |
| 5446 | ("inconsistent pv lock %p %p for page %p", |
| 5447 | lock, VM_PAGE_TO_PV_LIST_LOCK(m), m)); |
| 5448 | PMAP_UNLOCK(pmap); |
| 5449 | } |
| 5450 | TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) { |
| 5451 | pmap = PV_PMAP(pv); |
| 5452 | PMAP_ASSERT_STAGE1(pmap); |
| 5453 | if (!PMAP_TRYLOCK(pmap)) { |
| 5454 | pvh_gen = pvh->pv_gen; |
| 5455 | md_gen = m->md.pv_gen; |
| 5456 | rw_wunlock(lock); |
| 5457 | PMAP_LOCK(pmap); |
| 5458 | rw_wlock(lock); |
| 5459 | if (pvh_gen != pvh->pv_gen || |
| 5460 | md_gen != m->md.pv_gen) { |
| 5461 | PMAP_UNLOCK(pmap); |
| 5462 | rw_wunlock(lock); |
| 5463 | goto retry_pv_loop; |
nothing calls this directly
no test coverage detected