| 1950 | */ |
| 1951 | |
| 1952 | void |
| 1953 | pmap_remove_all(vm_page_t m) |
| 1954 | { |
| 1955 | pv_entry_t pv; |
| 1956 | pmap_t pmap; |
| 1957 | pd_entry_t *pde; |
| 1958 | pt_entry_t *pte, tpte; |
| 1959 | |
| 1960 | KASSERT((m->oflags & VPO_UNMANAGED) == 0, |
| 1961 | ("pmap_remove_all: page %p is not managed", m)); |
| 1962 | rw_wlock(&pvh_global_lock); |
| 1963 | |
| 1964 | if (m->md.pv_flags & PV_TABLE_REF) |
| 1965 | vm_page_aflag_set(m, PGA_REFERENCED); |
| 1966 | |
| 1967 | while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) { |
| 1968 | pmap = PV_PMAP(pv); |
| 1969 | PMAP_LOCK(pmap); |
| 1970 | |
| 1971 | /* |
| 1972 | * If it's last mapping writeback all caches from |
| 1973 | * the page being destroyed |
| 1974 | */ |
| 1975 | if (TAILQ_NEXT(pv, pv_list) == NULL) |
| 1976 | mips_dcache_wbinv_range_index(pv->pv_va, PAGE_SIZE); |
| 1977 | |
| 1978 | pmap->pm_stats.resident_count--; |
| 1979 | |
| 1980 | pde = pmap_pde(pmap, pv->pv_va); |
| 1981 | KASSERT(pde != NULL && *pde != 0, ("pmap_remove_all: pde")); |
| 1982 | pte = pmap_pde_to_pte(pde, pv->pv_va); |
| 1983 | |
| 1984 | tpte = *pte; |
| 1985 | if (is_kernel_pmap(pmap)) |
| 1986 | *pte = PTE_G; |
| 1987 | else |
| 1988 | *pte = 0; |
| 1989 | |
| 1990 | if (pte_test(&tpte, PTE_W)) |
| 1991 | pmap->pm_stats.wired_count--; |
| 1992 | |
| 1993 | /* |
| 1994 | * Update the vm_page_t clean and reference bits. |
| 1995 | */ |
| 1996 | if (pte_test(&tpte, PTE_D)) { |
| 1997 | KASSERT(!pte_test(&tpte, PTE_RO), |
| 1998 | ("%s: modified page not writable: va: %p, pte: %#jx", |
| 1999 | __func__, (void *)pv->pv_va, (uintmax_t)tpte)); |
| 2000 | vm_page_dirty(m); |
| 2001 | } |
| 2002 | |
| 2003 | if (!pmap_unuse_pt(pmap, pv->pv_va, *pde)) |
| 2004 | pmap_invalidate_page(pmap, pv->pv_va); |
| 2005 | |
| 2006 | TAILQ_REMOVE(&m->md.pv_list, pv, pv_list); |
| 2007 | free_pv_entry(pmap, pv); |
| 2008 | PMAP_UNLOCK(pmap); |
| 2009 | } |
no test coverage detected