VHE: MM: Add flags to support EL0/User mappings and non global mappings
Added flags and support for enabling EL0 mappings and non-global
mappings when VHE is enabled. This will be used to map EL0 partitions.
Change-Id: Ib6b142d36ecde63c9da46547a7f958deabf8fd7a
Signed-off-by: Raghu Krishnamurthy <raghu.ncstate@gmail.com>
diff --git a/inc/hf/mm.h b/inc/hf/mm.h
index b8ed221..901a799 100644
--- a/inc/hf/mm.h
+++ b/inc/hf/mm.h
@@ -62,6 +62,12 @@
#define MM_MODE_UNOWNED UINT32_C(0x0020)
#define MM_MODE_SHARED UINT32_C(0x0040)
+/* Specifies if a mapping will be a user mapping(EL0). */
+#define MM_MODE_USER UINT32_C(0x0200)
+
+/* Map page as non-global. */
+#define MM_MODE_NG UINT32_C(0x0100) /* non-global */
+
/* The mask for a mode that is considered unmapped. */
#define MM_MODE_UNMAPPED_MASK (MM_MODE_INVALID | MM_MODE_UNOWNED)
diff --git a/src/arch/aarch64/mm.c b/src/arch/aarch64/mm.c
index 17e9884..bc259f3 100644
--- a/src/arch/aarch64/mm.c
+++ b/src/arch/aarch64/mm.c
@@ -29,6 +29,7 @@
#define PTE_TABLE (UINT64_C(1) << 1)
#define STAGE1_XN (UINT64_C(1) << 54)
+#define STAGE1_UXN (UINT64_C(1) << 54)
#define STAGE1_PXN (UINT64_C(1) << 53)
#define STAGE1_CONTIGUOUS (UINT64_C(1) << 52)
#define STAGE1_DBM (UINT64_C(1) << 51)
@@ -44,6 +45,7 @@
#define STAGE1_READONLY UINT64_C(2)
#define STAGE1_READWRITE UINT64_C(0)
+#define STAGE1_AP_USER_RW UINT64_C(1)
#define STAGE1_DEVICEINDX UINT64_C(0)
#define STAGE1_NORMALINDX UINT64_C(1)
@@ -442,19 +444,31 @@
}
#endif
+ /*
+ * STAGE1_XN can be XN or UXN depending on if the EL2
+ * translation regime uses one VA range or two VA ranges(VHE).
+ * PXN is res0 when the translation regime does not support two
+ * VA ranges.
+ */
+ if (mode & MM_MODE_X) {
+ if (has_vhe_support()) {
+ attrs |=
+ (mode & MM_MODE_USER) ? STAGE1_PXN : STAGE1_UXN;
+ }
- /* Define the execute bits. */
- if (!(mode & MM_MODE_X)) {
- attrs |= STAGE1_XN;
- }
#if BRANCH_PROTECTION
- else {
/* Mark code pages as Guarded Pages if BTI is supported. */
if (is_arch_feat_bti_supported()) {
attrs |= STAGE1_GP;
}
- }
#endif
+ } else {
+ if (has_vhe_support()) {
+ attrs |= (STAGE1_UXN | STAGE1_PXN);
+ } else {
+ attrs |= STAGE1_XN;
+ }
+ }
/* Define the read/write bits. */
if (mode & MM_MODE_W) {
@@ -463,6 +477,14 @@
attrs |= STAGE1_AP(STAGE1_READONLY);
}
+ if (has_vhe_support()) {
+ attrs |= (mode & MM_MODE_USER) ? STAGE1_AP(STAGE1_AP_USER_RW)
+ : 0;
+ if (mode & MM_MODE_NG) {
+ attrs |= STAGE1_NG;
+ }
+ }
+
/* Define the memory attribute bits. */
if (mode & MM_MODE_D) {
attrs |= STAGE1_ATTRINDX(STAGE1_DEVICEINDX);
@@ -617,7 +639,12 @@
block_attrs |= STAGE1_AP2;
}
if (table_attrs & TABLE_APTABLE0) {
- block_attrs &= ~STAGE1_AP1;
+ /* When two VA ranges are supported, AP1 is valid */
+ if (has_vhe_support()) {
+ block_attrs |= STAGE1_AP1;
+ } else {
+ block_attrs &= ~STAGE1_AP1;
+ }
}
if (table_attrs & TABLE_XNTABLE) {
block_attrs |= STAGE1_XN;