From bcbe19afaa7a19083164dd1be80c741d23ee9caf Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Tue, 14 Jun 2016 16:29:04 +0100 Subject: xlat lib: Refactor mmap_desc() function This patch clarifies the mmap_desc() function by adding some comments and reorganising its code. No functional change has been introduced. Change-Id: I873493be17b4e60a89c1dc087dd908b425065401 --- lib/xlat_tables/xlat_tables_common.c | 60 ++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 17 deletions(-) (limited to 'lib') diff --git a/lib/xlat_tables/xlat_tables_common.c b/lib/xlat_tables/xlat_tables_common.c index fd100846..a8401894 100644 --- a/lib/xlat_tables/xlat_tables_common.c +++ b/lib/xlat_tables/xlat_tables_common.c @@ -194,30 +194,56 @@ void mmap_add(const mmap_region_t *mm) static uint64_t mmap_desc(unsigned attr, unsigned long long addr_pa, int level) { - uint64_t desc = addr_pa; + uint64_t desc; int mem_type; - desc |= level == 3 ? TABLE_DESC : BLOCK_DESC; - - desc |= attr & MT_NS ? LOWER_ATTRS(NS) : 0; - - desc |= attr & MT_RW ? LOWER_ATTRS(AP_RW) : LOWER_ATTRS(AP_RO); - + desc = addr_pa; + desc |= (level == 3) ? TABLE_DESC : BLOCK_DESC; + desc |= (attr & MT_NS) ? LOWER_ATTRS(NS) : 0; + desc |= (attr & MT_RW) ? LOWER_ATTRS(AP_RW) : LOWER_ATTRS(AP_RO); desc |= LOWER_ATTRS(ACCESS_FLAG); + /* + * Deduce shareability domain and executability of the memory region + * from the memory type. + * + * Data accesses to device memory and non-cacheable normal memory are + * coherent for all observers in the system, and correspondingly are + * always treated as being Outer Shareable. Therefore, for these 2 types + * of memory, it is not strictly needed to set the shareability field + * in the translation tables. + */ mem_type = MT_TYPE(attr); - if (mem_type == MT_MEMORY) { - desc |= LOWER_ATTRS(ATTR_IWBWA_OWBWA_NTR_INDEX | ISH); - if (attr & MT_RW) - desc |= UPPER_ATTRS(XN); - } else if (mem_type == MT_NON_CACHEABLE) { - desc |= LOWER_ATTRS(ATTR_NON_CACHEABLE_INDEX | OSH); - if (attr & MT_RW) - desc |= UPPER_ATTRS(XN); - } else { - assert(mem_type == MT_DEVICE); + if (mem_type == MT_DEVICE) { desc |= LOWER_ATTRS(ATTR_DEVICE_INDEX | OSH); + /* + * Always map device memory as execute-never. + * This is to avoid the possibility of a speculative instruction + * fetch, which could be an issue if this memory region + * corresponds to a read-sensitive peripheral. + */ desc |= UPPER_ATTRS(XN); + } else { /* Normal memory */ + /* + * Always map read-write normal memory as execute-never. + * (Trusted Firmware doesn't self-modify its code, therefore + * R/W memory is reserved for data storage, which must not be + * executable.) + * Note that setting the XN bit here is for consistency only. + * The enable_mmu_elx() function sets the SCTLR_EL3.WXN bit, + * which makes any writable memory region to be treated as + * execute-never, regardless of the value of the XN bit in the + * translation table. + */ + if (attr & MT_RW) + desc |= UPPER_ATTRS(XN); + + if (mem_type == MT_MEMORY) { + desc |= LOWER_ATTRS(ATTR_IWBWA_OWBWA_NTR_INDEX | ISH); + } else { + assert(mem_type == MT_NON_CACHEABLE); + desc |= LOWER_ATTRS(ATTR_NON_CACHEABLE_INDEX | OSH); + } } debug_print((mem_type == MT_MEMORY) ? "MEM" : -- cgit From b9161469fa95d290ba448d65e1d886ec1ff091e5 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Tue, 14 Jun 2016 16:31:09 +0100 Subject: xlat lib: Introduce MT_EXECUTE/MT_EXECUTE_NEVER attributes This patch introduces the MT_EXECUTE/MT_EXECUTE_NEVER memory mapping attributes in the translation table library to specify the access permissions for instruction execution of a memory region. These new attributes should be used only for normal, read-only memory regions. For other types of memory, the translation table library still enforces the following rules, regardless of the MT_EXECUTE/MT_EXECUTE_NEVER attribute: - Device memory is always marked as execute-never. - Read-write normal memory is always marked as execute-never. Change-Id: I8bd27800a8c1d8ac1559910caf4a4840cf25b8b0 --- lib/xlat_tables/xlat_tables_common.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/xlat_tables/xlat_tables_common.c b/lib/xlat_tables/xlat_tables_common.c index a8401894..e1448b94 100644 --- a/lib/xlat_tables/xlat_tables_common.c +++ b/lib/xlat_tables/xlat_tables_common.c @@ -234,8 +234,11 @@ static uint64_t mmap_desc(unsigned attr, unsigned long long addr_pa, * which makes any writable memory region to be treated as * execute-never, regardless of the value of the XN bit in the * translation table. + * + * For read-only memory, rely on the MT_EXECUTE/MT_EXECUTE_NEVER + * attribute to figure out the value of the XN bit. */ - if (attr & MT_RW) + if ((attr & MT_RW) || (attr & MT_EXECUTE_NEVER)) desc |= UPPER_ATTRS(XN); if (mem_type == MT_MEMORY) { @@ -250,7 +253,7 @@ static uint64_t mmap_desc(unsigned attr, unsigned long long addr_pa, ((mem_type == MT_NON_CACHEABLE) ? "NC" : "DEV")); debug_print(attr & MT_RW ? "-RW" : "-RO"); debug_print(attr & MT_NS ? "-NS" : "-S"); - + debug_print(attr & MT_EXECUTE_NEVER ? "-XN" : "-EXEC"); return desc; } -- cgit From ed81f3ebbfb5abc7d0d250fbc71f297a904d71ae Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Tue, 5 Jul 2016 09:55:03 +0100 Subject: Introduce utils.h header file This patch introduces a new header file: include/lib/utils.h. Its purpose is to provide generic macros and helper functions that are independent of any BL image, architecture, platform and even not specific to Trusted Firmware. For now, it contains only 2 macros: ARRAY_SIZE() and IS_POWER_OF_TWO(). These were previously defined in bl_common.h and xlat_tables.c respectively. bl_common.h includes utils.h to retain compatibility for platforms that relied on bl_common.h for the ARRAY_SIZE() macro. Upstream platform ports that use this macro have been updated to include utils.h. Change-Id: I960450f54134f25d1710bfbdc4184f12c049a9a9 --- lib/xlat_tables/aarch64/xlat_tables.c | 3 +-- lib/xlat_tables/xlat_tables_common.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c index 051e46a2..19eb7d5d 100644 --- a/lib/xlat_tables/aarch64/xlat_tables.c +++ b/lib/xlat_tables/aarch64/xlat_tables.c @@ -33,11 +33,10 @@ #include #include #include +#include #include #include "../xlat_tables_private.h" -#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 diff --git a/lib/xlat_tables/xlat_tables_common.c b/lib/xlat_tables/xlat_tables_common.c index e1448b94..71e3efca 100644 --- a/lib/xlat_tables/xlat_tables_common.c +++ b/lib/xlat_tables/xlat_tables_common.c @@ -31,11 +31,11 @@ #include #include #include -#include #include #include #include #include +#include #include #if LOG_LEVEL >= LOG_LEVEL_VERBOSE -- cgit