xlat: simplify mmap_add_region_check parameters (#1101)

Use a mmap_region_t as parameter instead of getting a parameter for each
structure member. This reduces the scope of changes when adding members
to mmap_region_t.

Also align on the convention of using mm_cursor as a variable name for
the currently inspected region when iterating on the region array.

Change-Id: If40bc4351b56c64b214e60dda27276d11ce9dbb3
Signed-off-by: Douglas Raillard <douglas.raillard@arm.com>
This commit is contained in:
Douglas Raillard 2017-09-21 08:42:21 +01:00 committed by davidcunado-arm
parent ea12986b87
commit df312c5a2b
1 changed files with 51 additions and 30 deletions

View File

@ -608,11 +608,13 @@ void print_mmap(mmap_region_t *const mmap)
* ENOMEM: There is not enough memory in the mmap array. * ENOMEM: There is not enough memory in the mmap array.
* EPERM: Region overlaps another one in an invalid way. * EPERM: Region overlaps another one in an invalid way.
*/ */
static int mmap_add_region_check(xlat_ctx_t *ctx, unsigned long long base_pa, static int mmap_add_region_check(xlat_ctx_t *ctx, const mmap_region_t *mm)
uintptr_t base_va, size_t size,
mmap_attr_t attr)
{ {
mmap_region_t *mm = ctx->mmap; unsigned long long base_pa = mm->base_pa;
uintptr_t base_va = mm->base_va;
size_t size = mm->size;
mmap_attr_t attr = mm->attr;
unsigned long long end_pa = base_pa + size - 1; unsigned long long end_pa = base_pa + size - 1;
uintptr_t end_va = base_va + size - 1; uintptr_t end_va = base_va + size - 1;
@ -630,22 +632,27 @@ static int mmap_add_region_check(xlat_ctx_t *ctx, unsigned long long base_pa,
if ((base_pa + (unsigned long long)size - 1ULL) > ctx->pa_max_address) if ((base_pa + (unsigned long long)size - 1ULL) > ctx->pa_max_address)
return -ERANGE; return -ERANGE;
/* Check that there is space in the mmap array */ /* Check that there is space in the ctx->mmap array */
if (ctx->mmap[ctx->mmap_num - 1].size != 0) if (ctx->mmap[ctx->mmap_num - 1].size != 0)
return -ENOMEM; return -ENOMEM;
/* Check for PAs and VAs overlaps with all other regions */ /* Check for PAs and VAs overlaps with all other regions */
for (mm = ctx->mmap; mm->size; ++mm) { for (mmap_region_t *mm_cursor = ctx->mmap;
mm_cursor->size; ++mm_cursor) {
uintptr_t mm_end_va = mm->base_va + mm->size - 1; uintptr_t mm_cursor_end_va = mm_cursor->base_va
+ mm_cursor->size - 1;
/* /*
* Check if one of the regions is completely inside the other * Check if one of the regions is completely inside the other
* one. * one.
*/ */
int fully_overlapped_va = int fully_overlapped_va =
((base_va >= mm->base_va) && (end_va <= mm_end_va)) || ((base_va >= mm_cursor->base_va) &&
((mm->base_va >= base_va) && (mm_end_va <= end_va)); (end_va <= mm_cursor_end_va)) ||
((mm_cursor->base_va >= base_va) &&
(mm_cursor_end_va <= end_va));
/* /*
* Full VA overlaps are only allowed if both regions are * Full VA overlaps are only allowed if both regions are
@ -656,13 +663,18 @@ static int mmap_add_region_check(xlat_ctx_t *ctx, unsigned long long base_pa,
if (fully_overlapped_va) { if (fully_overlapped_va) {
#if PLAT_XLAT_TABLES_DYNAMIC #if PLAT_XLAT_TABLES_DYNAMIC
if ((attr & MT_DYNAMIC) || (mm->attr & MT_DYNAMIC)) if ((attr & MT_DYNAMIC) ||
(mm_cursor->attr & MT_DYNAMIC))
return -EPERM; return -EPERM;
#else
(void)attr;
#endif /* PLAT_XLAT_TABLES_DYNAMIC */ #endif /* PLAT_XLAT_TABLES_DYNAMIC */
if ((mm->base_va - mm->base_pa) != (base_va - base_pa)) if ((mm_cursor->base_va - mm_cursor->base_pa) !=
(base_va - base_pa))
return -EPERM; return -EPERM;
if ((base_va == mm->base_va) && (size == mm->size)) if ((base_va == mm_cursor->base_va) &&
(size == mm_cursor->size))
return -EPERM; return -EPERM;
} else { } else {
@ -672,13 +684,15 @@ static int mmap_add_region_check(xlat_ctx_t *ctx, unsigned long long base_pa,
* Partial overlaps are not allowed * Partial overlaps are not allowed
*/ */
unsigned long long mm_end_pa = unsigned long long mm_cursor_end_pa =
mm->base_pa + mm->size - 1; mm_cursor->base_pa + mm_cursor->size - 1;
int separated_pa = int separated_pa =
(end_pa < mm->base_pa) || (base_pa > mm_end_pa); (end_pa < mm_cursor->base_pa) ||
(base_pa > mm_cursor_end_pa);
int separated_va = int separated_va =
(end_va < mm->base_va) || (base_va > mm_end_va); (end_va < mm_cursor->base_va) ||
(base_va > mm_cursor_end_va);
if (!(separated_va && separated_pa)) if (!(separated_va && separated_pa))
return -EPERM; return -EPERM;
@ -703,8 +717,7 @@ void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
/* Static regions must be added before initializing the xlat tables. */ /* Static regions must be added before initializing the xlat tables. */
assert(!ctx->initialized); assert(!ctx->initialized);
ret = mmap_add_region_check(ctx, mm->base_pa, mm->base_va, mm->size, ret = mmap_add_region_check(ctx, mm);
mm->attr);
if (ret != 0) { if (ret != 0) {
ERROR("mmap_add_region_check() failed. error %d\n", ret); ERROR("mmap_add_region_check() failed. error %d\n", ret);
assert(0); assert(0);
@ -799,7 +812,10 @@ int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
if (!mm->size) if (!mm->size)
return 0; return 0;
ret = mmap_add_region_check(ctx, mm->base_pa, mm->base_va, mm->size, mm->attr | MT_DYNAMIC); /* Now this region is a dynamic one */
mm->attr |= MT_DYNAMIC;
ret = mmap_add_region_check(ctx, mm);
if (ret != 0) if (ret != 0)
return ret; return ret;
@ -808,14 +824,17 @@ int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
* static regions in mmap_add_region_ctx(). * static regions in mmap_add_region_ctx().
*/ */
while ((mm_cursor->base_va + mm_cursor->size - 1) < end_va && mm_cursor->size) while ((mm_cursor->base_va + mm_cursor->size - 1)
< end_va && mm_cursor->size)
++mm_cursor; ++mm_cursor;
while ((mm_cursor->base_va + mm_cursor->size - 1 == end_va) && (mm_cursor->size < mm->size)) while ((mm_cursor->base_va + mm_cursor->size - 1 == end_va)
&& (mm_cursor->size < mm->size))
++mm_cursor; ++mm_cursor;
/* Make room for new region by moving other regions up by one place */ /* Make room for new region by moving other regions up by one place */
memmove(mm_cursor + 1, mm_cursor, (uintptr_t)mm_last - (uintptr_t)mm_cursor); memmove(mm_cursor + 1, mm_cursor,
(uintptr_t)mm_last - (uintptr_t)mm_cursor);
/* /*
* Check we haven't lost the empty sentinal from the end of the array. * Check we haven't lost the empty sentinal from the end of the array.
@ -825,19 +844,20 @@ int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
assert(mm_last->size == 0); assert(mm_last->size == 0);
*mm_cursor = *mm; *mm_cursor = *mm;
mm_cursor->attr |= MT_DYNAMIC;
/* /*
* Update the translation tables if the xlat tables are initialized. If * Update the translation tables if the xlat tables are initialized. If
* not, this region will be mapped when they are initialized. * not, this region will be mapped when they are initialized.
*/ */
if (ctx->initialized) { if (ctx->initialized) {
uintptr_t end_va = xlat_tables_map_region(ctx, mm_cursor, 0, ctx->base_table, uintptr_t end_va = xlat_tables_map_region(ctx, mm_cursor,
ctx->base_table_entries, ctx->base_level); 0, ctx->base_table, ctx->base_table_entries,
ctx->base_level);
/* Failed to map, remove mmap entry, unmap and return error. */ /* Failed to map, remove mmap entry, unmap and return error. */
if (end_va != mm_cursor->base_va + mm_cursor->size - 1) { if (end_va != mm_cursor->base_va + mm_cursor->size - 1) {
memmove(mm_cursor, mm_cursor + 1, (uintptr_t)mm_last - (uintptr_t)mm_cursor); memmove(mm_cursor, mm_cursor + 1,
(uintptr_t)mm_last - (uintptr_t)mm_cursor);
/* /*
* Check if the mapping function actually managed to map * Check if the mapping function actually managed to map
@ -847,8 +867,8 @@ int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
return -ENOMEM; return -ENOMEM;
/* /*
* Something went wrong after mapping some table entries, * Something went wrong after mapping some table
* undo every change done up to this point. * entries, undo every change done up to this point.
*/ */
mmap_region_t unmap_mm = { mmap_region_t unmap_mm = {
.base_pa = 0, .base_pa = 0,
@ -856,8 +876,9 @@ int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
.size = end_va - mm->base_va, .size = end_va - mm->base_va,
.attr = 0 .attr = 0
}; };
xlat_tables_unmap_region(ctx, &unmap_mm, 0, ctx->base_table, xlat_tables_unmap_region(ctx,
ctx->base_table_entries, ctx->base_level); &unmap_mm, 0, ctx->base_table,
ctx->base_table_entries, ctx->base_level);
return -ENOMEM; return -ENOMEM;
} }