diff --git a/include/lib/xlat_tables.h b/include/lib/xlat_tables.h index 7d57521..b51a1de 100644 --- a/include/lib/xlat_tables.h +++ b/include/lib/xlat_tables.h @@ -134,6 +134,8 @@ #define MT_PERM_SHIFT 3 /* Security state (SECURE/NS) */ #define MT_SEC_SHIFT 4 +/* Access permissions for instruction execution (EXECUTE/EXECUTE_NEVER) */ +#define MT_EXECUTE_SHIFT 5 /* * Memory mapping attributes @@ -155,8 +157,21 @@ MT_SECURE = 0 << MT_SEC_SHIFT, MT_NS = 1 << MT_SEC_SHIFT, + + /* + * Access permissions for instruction execution are only relevant for + * normal read-only memory, i.e. MT_MEMORY | MT_RO. They are ignored + * (and potentially overridden) otherwise: + * - Device memory is always marked as execute-never. + * - Read-write normal memory is always marked as execute-never. + */ + MT_EXECUTE = 0 << MT_EXECUTE_SHIFT, + MT_EXECUTE_NEVER = 1 << MT_EXECUTE_SHIFT, } mmap_attr_t; +#define MT_CODE (MT_MEMORY | MT_RO | MT_EXECUTE) +#define MT_RO_DATA (MT_MEMORY | MT_RO | MT_EXECUTE_NEVER) + /* * Structure for specifying a single region of memory. */ diff --git a/lib/xlat_tables/xlat_tables_common.c b/lib/xlat_tables/xlat_tables_common.c index a840189..e1448b9 100644 --- a/lib/xlat_tables/xlat_tables_common.c +++ b/lib/xlat_tables/xlat_tables_common.c @@ -234,8 +234,11 @@ * 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 @@ ((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; }