FreeBSD/sys/i386/i386/pmap.c
/*
 * pmap_remove_pte: do the things to unmap a page in a process
 */
do the things to unmap a page in a process
do the things to unmap a page in a process
static int
pmap_remove_pte(pmap_t pmap, pt_entry_t *ptq, vm_offset_t va,
    struct spglist *free)
{
	pt_entry_t oldpte;
	vm_page_t m;
	rw_assert(&pvh_global_lock, RA_WLOCKED);
	PMAP_LOCK_ASSERT(pmap, MA_OWNED);
	oldpte = pte_load_clear(ptq);
	KASSERT(oldpte != 0,
	    ("pmap_remove_pte: pmap %p va %x zero pte", pmap, va));
	if (oldpte & PG_W)
		pmap->pm_stats.wired_count -= 1;
	if (oldpte & PG_G)
		pmap_invalidate_page(kernel_pmap, va);
	pmap->pm_stats.resident_count -= 1;
	if (oldpte & PG_MANAGED) {
		m = PHYS_TO_VM_PAGE(oldpte & PG_FRAME);
		if ((oldpte & (PG_M | PG_RW)) == (PG_M | PG_RW))
			vm_page_dirty(m);
		if (oldpte & PG_A)
			vm_page_aflag_set(m, PGA_REFERENCED);
		pmap_remove_entry(pmap, m, va);
	}
	return (pmap_unuse_pt(pmap, va, free));
}
static int pmap_remove_pte ( pmap_t pmap , pt_entry_t * ptq , vm_offset_t va , struct spglist * free ) { pt_entry_t oldpte ; vm_page_t m ; rw_assert ( & pvh_global_lock , RA_WLOCKED ) ; PMAP_LOCK_ASSERT ( pmap , MA_OWNED ) ; oldpte = pte_load_clear ( ptq ) ; KASSERT ( oldpte != 0 , ( " " , pmap , va ) ) ; if ( oldpte & PG_W ) pmap -> pm_stats . wired_count -= 1 ; if ( oldpte & PG_G ) pmap_invalidate_page ( kernel_pmap , va ) ; pmap -> pm_stats . resident_count -= 1 ; if ( oldpte & PG_MANAGED ) { m = PHYS_TO_VM_PAGE ( oldpte & PG_FRAME ) ; if ( ( oldpte & ( PG_M | PG_RW ) ) == ( PG_M | PG_RW ) ) vm_page_dirty ( m ) ; if ( oldpte & PG_A ) vm_page_aflag_set ( m , PGA_REFERENCED ) ; pmap_remove_entry ( pmap , m , va ) ; } return ( pmap_unuse_pt ( pmap , va , free ) ) ; }
pmap_remove_pte: do the things to unmap a page in a process
pmap_remove_pte : do the things to unmap a page in a process
/*
	 * Machines that don't support invlpg, also don't support
	 * PG_G.
	 */