* Clear the write and modified bits in each of the given page's mappings. */
| 5519 | * Clear the write and modified bits in each of the given page's mappings. |
| 5520 | */ |
| 5521 | void |
| 5522 | pmap_remove_write(vm_page_t m) |
| 5523 | { |
| 5524 | struct md_page *pvh; |
| 5525 | pv_entry_t next_pv, pv; |
| 5526 | pmap_t pmap; |
| 5527 | pt1_entry_t *pte1p; |
| 5528 | pt2_entry_t *pte2p, opte2; |
| 5529 | vm_offset_t va; |
| 5530 | |
| 5531 | KASSERT((m->oflags & VPO_UNMANAGED) == 0, |
| 5532 | ("%s: page %p is not managed", __func__, m)); |
| 5533 | vm_page_assert_busied(m); |
| 5534 | |
| 5535 | if (!pmap_page_is_write_mapped(m)) |
| 5536 | return; |
| 5537 | rw_wlock(&pvh_global_lock); |
| 5538 | sched_pin(); |
| 5539 | if ((m->flags & PG_FICTITIOUS) != 0) |
| 5540 | goto small_mappings; |
| 5541 | pvh = pa_to_pvh(VM_PAGE_TO_PHYS(m)); |
| 5542 | TAILQ_FOREACH_SAFE(pv, &pvh->pv_list, pv_next, next_pv) { |
| 5543 | va = pv->pv_va; |
| 5544 | pmap = PV_PMAP(pv); |
| 5545 | PMAP_LOCK(pmap); |
| 5546 | pte1p = pmap_pte1(pmap, va); |
| 5547 | if (!(pte1_load(pte1p) & PTE1_RO)) |
| 5548 | (void)pmap_demote_pte1(pmap, pte1p, va); |
| 5549 | PMAP_UNLOCK(pmap); |
| 5550 | } |
| 5551 | small_mappings: |
| 5552 | TAILQ_FOREACH(pv, &m->md.pv_list, pv_next) { |
| 5553 | pmap = PV_PMAP(pv); |
| 5554 | PMAP_LOCK(pmap); |
| 5555 | pte1p = pmap_pte1(pmap, pv->pv_va); |
| 5556 | KASSERT(!pte1_is_section(pte1_load(pte1p)), ("%s: found" |
| 5557 | " a section in page %p's pv list", __func__, m)); |
| 5558 | pte2p = pmap_pte2_quick(pmap, pv->pv_va); |
| 5559 | opte2 = pte2_load(pte2p); |
| 5560 | if (!(opte2 & PTE2_RO)) { |
| 5561 | pte2_store(pte2p, opte2 | PTE2_RO | PTE2_NM); |
| 5562 | if (pte2_is_dirty(opte2)) |
| 5563 | vm_page_dirty(m); |
| 5564 | pmap_tlb_flush(pmap, pv->pv_va); |
| 5565 | } |
| 5566 | PMAP_UNLOCK(pmap); |
| 5567 | } |
| 5568 | vm_page_aflag_clear(m, PGA_WRITEABLE); |
| 5569 | sched_unpin(); |
| 5570 | rw_wunlock(&pvh_global_lock); |
| 5571 | } |
| 5572 | |
| 5573 | /* |
| 5574 | * Apply the given advice to the specified range of addresses within the |
nothing calls this directly
no test coverage detected