FreeBSD/sys/arm64/arm64/pmap.c
/*
 *	Remove the given range of addresses from the specified map.
 *
 *	It is assumed that the start and end are properly
 *	rounded to the page size.
 */
Remove the given range of addresses from the specified map.
It is assumed that the start and end are properly
rounded to the page size.
Remove the given range of addresses from the specified map . It is assumed that the start and end are properly rounded to the page size .
void
pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
{
	struct rwlock *lock;
	vm_offset_t va, va_next;
	pd_entry_t *l0, *l1, *l2;
	pt_entry_t l3_paddr, *l3;
	struct spglist free;
	int anyvalid;
	if (pmap->pm_stats.resident_count == 0)
		return;
	anyvalid = 0;
	SLIST_INIT(&free);
	rw_rlock(&pvh_global_lock);
	PMAP_LOCK(pmap);
	lock = NULL;
	for (; sva < eva; sva = va_next) {
		if (pmap->pm_stats.resident_count == 0)
			break;
		l0 = pmap_l0(pmap, sva);
		if (pmap_load(l0) == 0) {
			va_next = (sva + L0_SIZE) & ~L0_OFFSET;
			if (va_next < sva)
				va_next = eva;
			continue;
		}
		l1 = pmap_l0_to_l1(l0, sva);
		if (pmap_load(l1) == 0) {
			va_next = (sva + L1_SIZE) & ~L1_OFFSET;
			if (va_next < sva)
				va_next = eva;
			continue;
		}
		va_next = (sva + L2_SIZE) & ~L2_OFFSET;
		if (va_next < sva)
			va_next = eva;
		l2 = pmap_l1_to_l2(l1, sva);
		if (l2 == NULL)
			continue;
		l3_paddr = pmap_load(l2);
		if ((l3_paddr & ATTR_DESCR_MASK) != L2_TABLE)
			continue;
		if (va_next > eva)
			va_next = eva;
		va = va_next;
		for (l3 = pmap_l2_to_l3(l2, sva); sva != va_next; l3++,
		    sva += L3_SIZE) {
			if (l3 == NULL)
				panic("l3 == NULL");
			if (pmap_load(l3) == 0) {
				if (va != va_next) {
					pmap_invalidate_range(pmap, va, sva);
					va = va_next;
				}
				continue;
			}
			if (va == va_next)
				va = sva;
			if (pmap_remove_l3(pmap, l3, sva, l3_paddr, &free,
			    &lock)) {
				sva += L3_SIZE;
				break;
			}
		}
		if (va != va_next)
			pmap_invalidate_range(pmap, va, sva);
	}
	if (lock != NULL)
		rw_wunlock(lock);
	if (anyvalid)
		pmap_invalidate_all(pmap);
	rw_runlock(&pvh_global_lock);	
	PMAP_UNLOCK(pmap);
	pmap_free_zero_pages(&free);
}
void pmap_remove ( pmap_t pmap , vm_offset_t sva , vm_offset_t eva ) { struct rwlock * lock ; vm_offset_t va , va_next ; pd_entry_t * l0 , * l1 , * l2 ; pt_entry_t l3_paddr , * l3 ; struct spglist free ; int anyvalid ; if ( pmap -> pm_stats . resident_count == 0 ) return ; anyvalid = 0 ; SLIST_INIT ( & free ) ; rw_rlock ( & pvh_global_lock ) ; PMAP_LOCK ( pmap ) ; lock = NULL ; for ( ; sva < eva ; sva = va_next ) { if ( pmap -> pm_stats . resident_count == 0 ) break ; l0 = pmap_l0 ( pmap , sva ) ; if ( pmap_load ( l0 ) == 0 ) { va_next = ( sva + L0_SIZE ) & ~ L0_OFFSET ; if ( va_next < sva ) va_next = eva ; continue ; } l1 = pmap_l0_to_l1 ( l0 , sva ) ; if ( pmap_load ( l1 ) == 0 ) { va_next = ( sva + L1_SIZE ) & ~ L1_OFFSET ; if ( va_next < sva ) va_next = eva ; continue ; } va_next = ( sva + L2_SIZE ) & ~ L2_OFFSET ; if ( va_next < sva ) va_next = eva ; l2 = pmap_l1_to_l2 ( l1 , sva ) ; if ( l2 == NULL ) continue ; l3_paddr = pmap_load ( l2 ) ; if ( ( l3_paddr & ATTR_DESCR_MASK ) != L2_TABLE ) continue ; if ( va_next > eva ) va_next = eva ; va = va_next ; for ( l3 = pmap_l2_to_l3 ( l2 , sva ) ; sva != va_next ; l3 ++ , sva += L3_SIZE ) { if ( l3 == NULL ) panic ( " " ) ; if ( pmap_load ( l3 ) == 0 ) { if ( va != va_next ) { pmap_invalidate_range ( pmap , va , sva ) ; va = va_next ; } continue ; } if ( va == va_next ) va = sva ; if ( pmap_remove_l3 ( pmap , l3 , sva , l3_paddr , & free , & lock ) ) { sva += L3_SIZE ; break ; } } if ( va != va_next ) pmap_invalidate_range ( pmap , va , sva ) ; } if ( lock != NULL ) rw_wunlock ( lock ) ; if ( anyvalid ) pmap_invalidate_all ( pmap ) ; rw_runlock ( & pvh_global_lock ) ; PMAP_UNLOCK ( pmap ) ; pmap_free_zero_pages ( & free ) ; }
Remove the given range of addresses from the specified map.
Remove the given range of addresses from the specified map .
/*
	 * Perform an unsynchronized read.  This is, however, safe.
	 */ /*
		 * Calculate index for next page table.
		 */ /*
		 * Weed out invalid mappings.
		 */ /*
		 * Limit our scan to either the end of the va represented
		 * by the current page table page, or to the end of the
		 * range being removed.
		 */