lib/xlat_tables_v2/xlat_tables_core.c
/*
 * Function that verifies that a region can be mapped.
 * Returns:
 *        0: Success, the mapping is allowed.
 *   EINVAL: Invalid values were used as arguments.
 *   ERANGE: The memory limits were surpassed.
 *   ENOMEM: There is not enough memory in the mmap array.
 *    EPERM: Region overlaps another one in an invalid way.
 */
Function that verifies that a region can be mapped.
Returns:
0: Success, the mapping is allowed.
EINVAL: Invalid values were used as arguments.
ERANGE: The memory limits were surpassed.
ENOMEM: There is not enough memory in the mmap array.
EPERM: Region overlaps another one in an invalid way.
Function that verifies that a region can be mapped . Returns : 0 : Success the mapping is allowed . EINVAL : Invalid values were used as arguments . ERANGE : The memory limits were surpassed . ENOMEM : There is not enough memory in the mmap array . EPERM : Region overlaps another one in an invalid way .
static int mmap_add_region_check(const xlat_ctx_t *ctx, const mmap_region_t *mm)
{
	unsigned long long base_pa = mm->base_pa;
	uintptr_t base_va = mm->base_va;
	size_t size = mm->size;
	size_t granularity = mm->granularity;
	unsigned long long end_pa = base_pa + size - 1U;
	uintptr_t end_va = base_va + size - 1U;
	if (!IS_PAGE_ALIGNED(base_pa) || !IS_PAGE_ALIGNED(base_va) ||
			!IS_PAGE_ALIGNED(size))
		return -EINVAL;
	if ((granularity != XLAT_BLOCK_SIZE(1U)) &&
		(granularity != XLAT_BLOCK_SIZE(2U)) &&
		(granularity != XLAT_BLOCK_SIZE(3U))) {
		return -EINVAL;
	}
	if ((base_pa > end_pa) || (base_va > end_va))
		return -ERANGE;
	if ((base_va + (uintptr_t)size - (uintptr_t)1) > ctx->va_max_address)
		return -ERANGE;
	if ((base_pa + (unsigned long long)size - 1ULL) > ctx->pa_max_address)
		return -ERANGE;
	if (ctx->mmap[ctx->mmap_num - 1].size != 0U)
		return -ENOMEM;
	for (const mmap_region_t *mm_cursor = ctx->mmap;
	     mm_cursor->size != 0U; ++mm_cursor) {
		uintptr_t mm_cursor_end_va = mm_cursor->base_va
							+ mm_cursor->size - 1U;
		int fully_overlapped_va =
			(((base_va >= mm_cursor->base_va) &&
					(end_va <= mm_cursor_end_va)) ||
			 ((mm_cursor->base_va >= base_va) &&
						(mm_cursor_end_va <= end_va)))
			? 1 : 0;
		if (fully_overlapped_va != 0) {
#if PLAT_XLAT_TABLES_DYNAMIC
			if (((mm->attr & MT_DYNAMIC) != 0U) ||
			    ((mm_cursor->attr & MT_DYNAMIC) != 0U))
				return -EPERM;
#endif 
			if ((mm_cursor->base_va - mm_cursor->base_pa) !=
							(base_va - base_pa))
				return -EPERM;
			if ((base_va == mm_cursor->base_va) &&
						(size == mm_cursor->size))
				return -EPERM;
		} else {
			unsigned long long mm_cursor_end_pa =
				     mm_cursor->base_pa + mm_cursor->size - 1U;
			int separated_pa = ((end_pa < mm_cursor->base_pa) ||
				(base_pa > mm_cursor_end_pa)) ? 1 : 0;
			int separated_va = ((end_va < mm_cursor->base_va) ||
				(base_va > mm_cursor_end_va)) ? 1 : 0;
			if ((separated_va == 0) || (separated_pa == 0))
				return -EPERM;
		}
	}
	return 0;
}
static int mmap_add_region_check ( const xlat_ctx_t * ctx , const mmap_region_t * mm ) { unsigned long long base_pa = mm -> base_pa ; uintptr_t base_va = mm -> base_va ; size_t size = mm -> size ; size_t granularity = mm -> granularity ; unsigned long long end_pa = base_pa + size - 1U ; uintptr_t end_va = base_va + size - 1U ; if ( ! IS_PAGE_ALIGNED ( base_pa ) || ! IS_PAGE_ALIGNED ( base_va ) || ! IS_PAGE_ALIGNED ( size ) ) return - EINVAL ; if ( ( granularity != XLAT_BLOCK_SIZE ( 1U ) ) && ( granularity != XLAT_BLOCK_SIZE ( 2U ) ) && ( granularity != XLAT_BLOCK_SIZE ( 3U ) ) ) { return - EINVAL ; } if ( ( base_pa > end_pa ) || ( base_va > end_va ) ) return - ERANGE ; if ( ( base_va + ( uintptr_t ) size - ( uintptr_t ) 1 ) > ctx -> va_max_address ) return - ERANGE ; if ( ( base_pa + ( unsigned long long ) size - 1ULL ) > ctx -> pa_max_address ) return - ERANGE ; if ( ctx -> mmap [ ctx -> mmap_num - 1 ] . size != 0U ) return - ENOMEM ; for ( const mmap_region_t * mm_cursor = ctx -> mmap ; mm_cursor -> size != 0U ; ++ mm_cursor ) { uintptr_t mm_cursor_end_va = mm_cursor -> base_va + mm_cursor -> size - 1U ; int fully_overlapped_va = ( ( ( base_va >= mm_cursor -> base_va ) && ( end_va <= mm_cursor_end_va ) ) || ( ( mm_cursor -> base_va >= base_va ) && ( mm_cursor_end_va <= end_va ) ) ) ? 1 : 0 ; if ( fully_overlapped_va != 0 ) { #if PLAT_XLAT_TABLES_DYNAMIC if ( ( ( mm -> attr & MT_DYNAMIC ) != 0U ) || ( ( mm_cursor -> attr & MT_DYNAMIC ) != 0U ) ) return - EPERM ; #endif if ( ( mm_cursor -> base_va - mm_cursor -> base_pa ) != ( base_va - base_pa ) ) return - EPERM ; if ( ( base_va == mm_cursor -> base_va ) && ( size == mm_cursor -> size ) ) return - EPERM ; } else { unsigned long long mm_cursor_end_pa = mm_cursor -> base_pa + mm_cursor -> size - 1U ; int separated_pa = ( ( end_pa < mm_cursor -> base_pa ) || ( base_pa > mm_cursor_end_pa ) ) ? 1 : 0 ; int separated_va = ( ( end_va < mm_cursor -> base_va ) || ( base_va > mm_cursor_end_va ) ) ? 1 : 0 ; if ( ( separated_va == 0 ) || ( separated_pa == 0 ) ) return - EPERM ; } } return 0 ; }
Function that verifies that a region can be mapped.
Function that verifies that a region can be mapped .
/* Check for overflows */ /* Check that there is space in the ctx->mmap array */ /* Check for PAs and VAs overlaps with all other regions */ /*
		 * Check if one of the regions is completely inside the other
		 * one.
		 */ /*
		 * Full VA overlaps are only allowed if both regions are
		 * identity mapped (zero offset) or have the same VA to PA
		 * offset. Also, make sure that it's not the exact same area.
		 * This can only be done with static regions.
		 */ /* PLAT_XLAT_TABLES_DYNAMIC */ /*
			 * If the regions do not have fully overlapping VAs,
			 * then they must have fully separated VAs and PAs.
			 * Partial overlaps are not allowed
			 */