diff options
author | Antonio Nino Diaz <antonio.ninodiaz@arm.com> | 2016-12-13 15:02:31 +0000 |
---|---|---|
committer | Antonio Nino Diaz <antonio.ninodiaz@arm.com> | 2016-12-13 15:38:19 +0000 |
commit | 2240f45b1aa238b0bfa6b9ec608ec1574e5088bd (patch) | |
tree | 115f709b268f994cda8578245bda56fc546b0e17 /lib | |
parent | e60e74bd26ca009f005541b93baeb55e465e9d5f (diff) |
Forbid block descriptors in initial xlat table levels
In AArch64, depending on the granularity of the translation tables,
level 0 and/or level 1 of the translation tables may not support block
descriptors, only table descriptors.
This patch introduces a check to make sure that, even if theoretically
it could be possible to create a block descriptor to map a big memory
region, a new subtable will be created to describe its mapping.
Change-Id: Ieb9c302206bfa33fbaf0cdc6a5a82516d32ae2a7
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/xlat_tables/xlat_tables_common.c | 3 | ||||
-rw-r--r-- | lib/xlat_tables/xlat_tables_private.h | 30 |
2 files changed, 32 insertions, 1 deletions
diff --git a/lib/xlat_tables/xlat_tables_common.c b/lib/xlat_tables/xlat_tables_common.c index 448d25d8..81c4dc68 100644 --- a/lib/xlat_tables/xlat_tables_common.c +++ b/lib/xlat_tables/xlat_tables_common.c @@ -353,7 +353,8 @@ static mmap_region_t *init_xlation_table_inner(mmap_region_t *mm, if (mm->base_va > base_va + level_size - 1) { /* Next region is after this area. Nothing to map yet */ desc = INVALID_DESC; - } else { + /* Make sure that the current level allows block descriptors */ + } else if (level >= XLAT_BLOCK_LEVEL_MIN) { /* * Try to get attributes of this area. It will fail if * there are partially overlapping regions. On success, diff --git a/lib/xlat_tables/xlat_tables_private.h b/lib/xlat_tables/xlat_tables_private.h index 085a0c26..f0f656bd 100644 --- a/lib/xlat_tables/xlat_tables_private.h +++ b/lib/xlat_tables/xlat_tables_private.h @@ -58,6 +58,36 @@ CASSERT(IS_POWER_OF_TWO(PLAT_VIRT_ADDR_SPACE_SIZE), CASSERT(IS_POWER_OF_TWO(PLAT_PHY_ADDR_SPACE_SIZE), assert_valid_phy_addr_space_size); +/* + * In AArch32 state, the MMU only supports 4KB page granularity, which means + * that the first translation table level is either 1 or 2. Both of them are + * allowed to have block and table descriptors. See section G4.5.6 of the + * ARMv8-A Architecture Reference Manual (DDI 0487A.k) for more information. + * + * In AArch64 state, the MMU may support 4 KB, 16 KB and 64 KB page + * granularity. For 4KB granularity, a level 0 table descriptor doesn't support + * block translation. For 16KB, the same thing happens to levels 0 and 1. For + * 64KB, same for level 1. See section D4.3.1 of the ARMv8-A Architecture + * Reference Manual (DDI 0487A.k) for more information. + * + * The define below specifies the first table level that allows block + * descriptors. + */ + +#ifdef AARCH32 + +# define XLAT_BLOCK_LEVEL_MIN 1 + +#else /* if AArch64 */ + +# if PAGE_SIZE == (4*1024) /* 4KB */ +# define XLAT_BLOCK_LEVEL_MIN 1 +# else /* 16KB or 64KB */ +# define XLAT_BLOCK_LEVEL_MIN 2 +# endif + +#endif /* AARCH32 */ + void print_mmap(void); void init_xlation_table(uintptr_t base_va, uint64_t *table, int level, uintptr_t *max_va, |