summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSandrine Bailleux <sandrine.bailleux@arm.com>2016-06-14 16:31:09 +0100
committerSandrine Bailleux <sandrine.bailleux@arm.com>2016-07-08 14:37:11 +0100
commitb9161469fa95d290ba448d65e1d886ec1ff091e5 (patch)
treef3a47715bba95e7884992303900689680388359a
parentbcbe19afaa7a19083164dd1be80c741d23ee9caf (diff)
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
-rw-r--r--include/lib/xlat_tables.h15
-rw-r--r--lib/xlat_tables/xlat_tables_common.c7
2 files changed, 20 insertions, 2 deletions
diff --git a/include/lib/xlat_tables.h b/include/lib/xlat_tables.h
index 7d57521b..b51a1de5 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 @@ 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.
*/
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;
}