xlat lib: Introduce MT_EXECUTE/MT_EXECUTE_NEVER attributes
authorSandrine Bailleux <sandrine.bailleux@arm.com>
Tue, 14 Jun 2016 15:31:09 +0000 (16:31 +0100)
committerSandrine Bailleux <sandrine.bailleux@arm.com>
Fri, 8 Jul 2016 13:37:11 +0000 (14:37 +0100)
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

include/lib/xlat_tables.h
lib/xlat_tables/xlat_tables_common.c

index 7d57521b7e6b42f458a2908f16e0704b018b325e..b51a1de5c413fd976c1ae8d97730a87587f936dd 100644 (file)
 #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 @@ typedef enum  {
 
        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.
  */
index a84018943d281b0bd48983289525d10f8b587afa..e1448b94de9642ebbc9690c62d89cfe7478d9eef 100644 (file)
@@ -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;
 }