* pmap_remove_l3: do the things to unmap a page in a process */
| 2911 | * pmap_remove_l3: do the things to unmap a page in a process |
| 2912 | */ |
| 2913 | static int |
| 2914 | pmap_remove_l3(pmap_t pmap, pt_entry_t *l3, vm_offset_t va, |
| 2915 | pd_entry_t l2e, struct spglist *free, struct rwlock **lockp) |
| 2916 | { |
| 2917 | struct md_page *pvh; |
| 2918 | pt_entry_t old_l3; |
| 2919 | vm_page_t m; |
| 2920 | |
| 2921 | PMAP_LOCK_ASSERT(pmap, MA_OWNED); |
| 2922 | old_l3 = pmap_load_clear(l3); |
| 2923 | pmap_invalidate_page(pmap, va); |
| 2924 | if (old_l3 & ATTR_SW_WIRED) |
| 2925 | pmap->pm_stats.wired_count -= 1; |
| 2926 | pmap_resident_count_dec(pmap, 1); |
| 2927 | if (old_l3 & ATTR_SW_MANAGED) { |
| 2928 | m = PHYS_TO_VM_PAGE(old_l3 & ~ATTR_MASK); |
| 2929 | if (pmap_pte_dirty(pmap, old_l3)) |
| 2930 | vm_page_dirty(m); |
| 2931 | if (old_l3 & ATTR_AF) |
| 2932 | vm_page_aflag_set(m, PGA_REFERENCED); |
| 2933 | CHANGE_PV_LIST_LOCK_TO_VM_PAGE(lockp, m); |
| 2934 | pmap_pvh_free(&m->md, pmap, va); |
| 2935 | if (TAILQ_EMPTY(&m->md.pv_list) && |
| 2936 | (m->flags & PG_FICTITIOUS) == 0) { |
| 2937 | pvh = page_to_pvh(m); |
| 2938 | if (TAILQ_EMPTY(&pvh->pv_list)) |
| 2939 | vm_page_aflag_clear(m, PGA_WRITEABLE); |
| 2940 | } |
| 2941 | } |
| 2942 | return (pmap_unuse_pt(pmap, va, l2e, free)); |
| 2943 | } |
| 2944 | |
| 2945 | /* |
| 2946 | * Remove the specified range of addresses from the L3 page table that is |
no test coverage detected