FreeBSD/sys/arm64/arm64/pmap.c
/*
 *	Set the physical protection on the
 *	specified range of this map as requested.
 */
Set the physical protection on the
specified range of this map as requested.
Set the physical protection on the specified range of this map as requested .
void
pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
{
	vm_offset_t va, va_next;
	pd_entry_t *l0, *l1, *l2;
	pt_entry_t *l3p, l3;
	if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
		pmap_remove(pmap, sva, eva);
		return;
	}
	if ((prot & VM_PROT_WRITE) == VM_PROT_WRITE)
		return;
	PMAP_LOCK(pmap);
	for (; sva < eva; sva = va_next) {
		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 || (pmap_load(l2) & ATTR_DESCR_MASK) != L2_TABLE)
			continue;
		if (va_next > eva)
			va_next = eva;
		va = va_next;
		for (l3p = pmap_l2_to_l3(l2, sva); sva != va_next; l3p++,
		    sva += L3_SIZE) {
			l3 = pmap_load(l3p);
			if (pmap_l3_valid(l3)) {
				pmap_set(l3p, ATTR_AP(ATTR_AP_RO));
				PTE_SYNC(l3p);
				pmap_invalidate_page(pmap, va);
			}
		}
	}
	PMAP_UNLOCK(pmap);
	pmap_invalidate_all(pmap);
}
void pmap_protect ( pmap_t pmap , vm_offset_t sva , vm_offset_t eva , vm_prot_t prot ) { vm_offset_t va , va_next ; pd_entry_t * l0 , * l1 , * l2 ; pt_entry_t * l3p , l3 ; if ( ( prot & VM_PROT_READ ) == VM_PROT_NONE ) { pmap_remove ( pmap , sva , eva ) ; return ; } if ( ( prot & VM_PROT_WRITE ) == VM_PROT_WRITE ) return ; PMAP_LOCK ( pmap ) ; for ( ; sva < eva ; sva = va_next ) { 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 || ( pmap_load ( l2 ) & ATTR_DESCR_MASK ) != L2_TABLE ) continue ; if ( va_next > eva ) va_next = eva ; va = va_next ; for ( l3p = pmap_l2_to_l3 ( l2 , sva ) ; sva != va_next ; l3p ++ , sva += L3_SIZE ) { l3 = pmap_load ( l3p ) ; if ( pmap_l3_valid ( l3 ) ) { pmap_set ( l3p , ATTR_AP ( ATTR_AP_RO ) ) ; PTE_SYNC ( l3p ) ; pmap_invalidate_page ( pmap , va ) ; } } } PMAP_UNLOCK ( pmap ) ; pmap_invalidate_all ( pmap ) ; }
Set the physical protection on the
      specified range of this map as requested.
Set the physical protection on the specified range of this map as requested .
/* XXX: Use pmap_invalidate_range */ /* TODO: Only invalidate entries we are touching */