fix(rmm): fix block mapping cases
This patch implements the following changes:
1. Fix in s2tte_check() for block entries.
S2TTE_L012_BLOCK is used instead of S2TTE_BLOCK which
includes the PTE attributes. This would cause assert()
if RTT_CREATE is called on a block mapping.
2. Fix smc_rtt_fold() use of 's2tte_pa'.
When the parent RTT is found at ('level' - 1), the entry
for 'level' (parent_s2tte) is read. This is then mapped to
table, which takes us to 'level'. As such it should be
considered 'level' when the s2tte_pa() is read.
This fixes triggered assert() below:
Assertion "false" failed rmm/lib/realm/src/s2tt.c:750, s2tte_pa
3. Fix smc_rtt_fold() to handle mix of RIPAS state
We could have a table with mix of RTTEs with differing
RIPAS. In this case, refcount=PTRS_PER_S2TTE but wouldn't
satisfy the cases for a successful fold. Fail this case
instead of triggering assert().
Signed-off-by: AlexeiFedorov <Alexei.Fedorov@arm.com>
Change-Id: I9c9285a527468a57b9f81d5b55728c91d8b0e7f7
diff --git a/lib/realm/src/s2tt.c b/lib/realm/src/s2tt.c
index 7b6f197..0f8a4bf 100644
--- a/lib/realm/src/s2tt.c
+++ b/lib/realm/src/s2tt.c
@@ -580,7 +580,7 @@
/* Only pages at L3 and valid blocks at L2 allowed */
if (((level == RTT_PAGE_LEVEL) && (desc_type == S2TTE_L3_PAGE)) ||
- ((level == RTT_MIN_BLOCK_LEVEL) && (desc_type == S2TTE_BLOCK))) {
+ ((level == RTT_MIN_BLOCK_LEVEL) && (desc_type == S2TTE_L012_BLOCK))) {
return true;
}
diff --git a/runtime/rmi/rtt.c b/runtime/rmi/rtt.c
index e474e5d..c138fbd 100644
--- a/runtime/rmi/rtt.c
+++ b/runtime/rmi/rtt.c
@@ -373,7 +373,7 @@
}
s2tte = s2tte_read(&table[0]);
- block_pa = s2tte_pa(s2tte, level - 1L);
+ block_pa = s2tte_pa(s2tte, level);
/*
* The table must also refer to a contiguous block through
@@ -385,9 +385,10 @@
parent_s2tte = s2tte_create_valid(block_pa, level - 1L);
} else if (table_maps_valid_ns_block(table, level)) {
parent_s2tte = s2tte_create_valid_ns(block_pa, level - 1L);
- /* This 'else' case should not happen */
+ /* The table contains mixed entries that cannot be folded */
} else {
- assert(false);
+ ret = pack_return_code(RMI_ERROR_RTT, level);
+ goto out_unmap_table;
}
__granule_refcount_dec(g_tbl, S2TTES_PER_S2TT);