* Clear the write and modified bits in each of the given page's mappings. */
| 2961 | * Clear the write and modified bits in each of the given page's mappings. |
| 2962 | */ |
| 2963 | void |
| 2964 | pmap_remove_write(vm_page_t m) |
| 2965 | { |
| 2966 | pmap_t pmap; |
| 2967 | pt_entry_t pbits, *pte; |
| 2968 | pv_entry_t pv; |
| 2969 | |
| 2970 | KASSERT((m->oflags & VPO_UNMANAGED) == 0, |
| 2971 | ("pmap_remove_write: page %p is not managed", m)); |
| 2972 | vm_page_assert_busied(m); |
| 2973 | |
| 2974 | if (!pmap_page_is_write_mapped(m)) |
| 2975 | return; |
| 2976 | rw_wlock(&pvh_global_lock); |
| 2977 | TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) { |
| 2978 | pmap = PV_PMAP(pv); |
| 2979 | PMAP_LOCK(pmap); |
| 2980 | pte = pmap_pte(pmap, pv->pv_va); |
| 2981 | KASSERT(pte != NULL && pte_test(pte, PTE_V), |
| 2982 | ("page on pv_list has no pte")); |
| 2983 | pbits = *pte; |
| 2984 | if (pte_test(&pbits, PTE_D)) { |
| 2985 | pte_clear(&pbits, PTE_D); |
| 2986 | vm_page_dirty(m); |
| 2987 | } |
| 2988 | pte_set(&pbits, PTE_RO); |
| 2989 | if (pbits != *pte) { |
| 2990 | *pte = pbits; |
| 2991 | pmap_update_page(pmap, pv->pv_va, pbits); |
| 2992 | } |
| 2993 | PMAP_UNLOCK(pmap); |
| 2994 | } |
| 2995 | vm_page_aflag_clear(m, PGA_WRITEABLE); |
| 2996 | rw_wunlock(&pvh_global_lock); |
| 2997 | } |
| 2998 | |
| 2999 | /* |
| 3000 | * pmap_ts_referenced: |
no test coverage detected