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:
parent
ea12986b87
commit
df312c5a2b
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue