aboutsummaryrefslogtreecommitdiff
path: root/lib/aarch64
diff options
context:
space:
mode:
authorKristina Martsenko <kristina.martsenko@arm.com>2016-02-11 18:11:56 +0000
committerSandrine Bailleux <sandrine.bailleux@arm.com>2016-03-07 09:13:34 +0000
commit2af926ddd47d9ce0043cad474c52292b0cbc6baf (patch)
treeeabc22002eb49c5d5c001c2520e97978f7a7da29 /lib/aarch64
parent9931932bfd3429aa8e98c33a26dfafcdbda71a43 (diff)
downloadtrusted-firmware-a-2af926ddd47d9ce0043cad474c52292b0cbc6baf.tar.gz
Initialize all translation table entries
The current translation table code maps in a series of regions, zeroing the unmapped table entries before and in between the mapped regions. It doesn't, however, zero the unmapped entries after the last mapped region, leaving those entries at whatever value that memory has initially. This is bad because those values can look like valid translation table entries, pointing to valid physical addresses. The CPU is allowed to do speculative reads from any such addresses. If the addresses point to device memory, the results can be unpredictable. This patch zeroes the translation table entries following the last mapped region, ensuring all table entries are either valid or zero (invalid). In addition, it limits the value of ADDR_SPACE_SIZE to those allowed by the architecture and supported by the current code (see D4.2.5 in the Architecture Reference Manual). This simplifies this patch a lot and ensures existing code doesn't do unexpected things. Change-Id: Ic28b6c3f89d73ef58fa80319a9466bb2c7131c21
Diffstat (limited to 'lib/aarch64')
-rw-r--r--lib/aarch64/xlat_tables.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/lib/aarch64/xlat_tables.c b/lib/aarch64/xlat_tables.c
index 2f2ca814eb..1e748a36a9 100644
--- a/lib/aarch64/xlat_tables.c
+++ b/lib/aarch64/xlat_tables.c
@@ -52,7 +52,17 @@
#define debug_print(...) ((void)0)
#endif
-CASSERT(ADDR_SPACE_SIZE > 0, assert_valid_addr_space_size);
+#define IS_POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0)
+
+/*
+ * The virtual address space size must be a power of two (as set in TCR.T0SZ).
+ * As we start the initial lookup at level 1, it must also be between 2 GB and
+ * 512 GB (with the virtual address size therefore 31 to 39 bits). See section
+ * D4.2.5 in the ARMv8-A Architecture Reference Manual (DDI 0487A.i) for more
+ * information.
+ */
+CASSERT(ADDR_SPACE_SIZE >= (1ull << 31) && ADDR_SPACE_SIZE <= (1ull << 39) &&
+ IS_POWER_OF_TWO(ADDR_SPACE_SIZE), assert_valid_addr_space_size);
#define UNSET_DESC ~0ul
@@ -207,7 +217,10 @@ static mmap_region_t *init_xlation_table(mmap_region_t *mm,
do {
unsigned long desc = UNSET_DESC;
- if (mm->base_va + mm->size <= base_va) {
+ if (!mm->size) {
+ /* Done mapping regions; finish zeroing the table */
+ desc = INVALID_DESC;
+ } else if (mm->base_va + mm->size <= base_va) {
/* Area now after the region so skip it */
++mm;
continue;
@@ -245,7 +258,7 @@ static mmap_region_t *init_xlation_table(mmap_region_t *mm,
*table++ = desc;
base_va += level_size;
- } while (mm->size && (base_va & level_index_mask));
+ } while ((base_va & level_index_mask) && (base_va < ADDR_SPACE_SIZE));
return mm;
}