fix(lib/s2tt) : PA must be <= 48 bits for LPA2 disabled Realm
If FEAT_LPA2 is disabled for the realm, add a check to
ensure that PA for some args of RTT related commands is
within 48 bits.
Change-Id: If1647a1848823e63cccf07f46876367c165ef8a5
Signed-off-by: Shruti Gupta <shruti.gupta@arm.com>
diff --git a/lib/s2tt/include/s2tt.h b/lib/s2tt/include/s2tt.h
index cc7d0fd..89a30fc 100644
--- a/lib/s2tt/include/s2tt.h
+++ b/lib/s2tt/include/s2tt.h
@@ -40,8 +40,10 @@
#define S2TT_MIN_IPA_BITS U(32)
#define S2TT_MAX_IPA_BITS U(48)
+#define S2TT_MAX_PA_BITS U(48)
#define S2TT_MAX_IPA_BITS_LPA2 U(52)
+#define S2TT_MAX_PA_BITS_LPA2 U(52)
#define S2TT_MAX_IPA_SIZE_LPA2 (UL(1) << S2TT_MAX_IPA_BITS_LPA2)
#define S2TT_MIN_STARTING_LEVEL (0)
diff --git a/lib/s2tt/src/s2tt.c b/lib/s2tt/src/s2tt.c
index 3ad094c..0cde136 100644
--- a/lib/s2tt/src/s2tt.c
+++ b/lib/s2tt/src/s2tt.c
@@ -563,6 +563,8 @@
* Test that all fields that are not controlled by the host are zero
* and that the output address is correctly aligned. Note that
* the host is permitted to map any physical address outside PAR.
+ * Note that this also checks for the case when FEAT_LPA2 is disabled
+ * for the Realm, then the PA in `s2tte` must be <= 48 bits wide.
*/
if ((s2tte & ~mask) != 0UL) {
return false;
diff --git a/runtime/rmi/rtt.c b/runtime/rmi/rtt.c
index 2e46710..1792efc 100644
--- a/runtime/rmi/rtt.c
+++ b/runtime/rmi/rtt.c
@@ -112,6 +112,18 @@
buffer_unmap(rd);
/*
+ * If LPA2 is disabled for the realm, then `rtt_addr` must not be
+ * more than 48 bits wide.
+ */
+ if (!s2_ctx.enable_lpa2) {
+ if ((rtt_addr >= (UL(1) << S2TT_MAX_PA_BITS))) {
+ granule_unlock(g_rd);
+ granule_unlock(g_tbl);
+ return RMI_ERROR_INPUT;
+ }
+ }
+
+ /*
* Lock the RTT root. Enforcing locking order RD->RTT is enough to
* ensure deadlock free locking guarantee.
*/
@@ -908,6 +920,18 @@
}
s2_ctx = &(rd->s2_ctx);
+
+ /*
+ * If LPA2 is disabled for the realm, then `data_addr` must not be
+ * more than 48 bits wide.
+ */
+ if (!s2_ctx->enable_lpa2) {
+ if ((data_addr >= (UL(1) << S2TT_MAX_PA_BITS))) {
+ ret = RMI_ERROR_INPUT;
+ goto out_unmap_rd;
+ }
+ }
+
granule_lock(s2_ctx->g_rtt, GRANULE_STATE_RTT);
s2tt_walk_lock_unlock(s2_ctx, map_addr, S2TT_PAGE_LEVEL, &wi);