test(realm): handle permission fault for planes
Add support for handling permission fault in planes.
Set s2ap in RTTs.
Signed-off-by: Shruti Gupta <shruti.gupta@arm.com>
Change-Id: I590fc5a1c43357b117fa5cb76e8c699c4c7eebad
diff --git a/realm/realm_plane.c b/realm/realm_plane.c
index 7affc15..9a604c6 100644
--- a/realm/realm_plane.c
+++ b/realm/realm_plane.c
@@ -67,18 +67,45 @@
}
/* return true to re-enter PlaneN, false to exit to P0 */
-static bool handle_plane_exit(u_register_t plane_index,
+u_register_t handle_plane_exit(u_register_t plane_index,
u_register_t perm_index,
rsi_plane_run *run)
{
u_register_t ec = EC_BITS(run->exit.esr);
u_register_t ret;
+ if (((run->exit.esr & ISS_FSC_MASK) >= FSC_L0_PERM_FAULT) &&
+ ((run->exit.esr & ISS_FSC_MASK) <= FSC_L3_PERM_FAULT)) {
+
+ /* If Plane N exit is due to permission fault, change s2ap */
+ u_register_t base, new_base, response, ret;
+ u_register_t new_cookie = 0UL;
+
+ new_base = base = (run->exit.far & ~PAGE_SIZE_MASK);
+
+ VERBOSE("P0 set s2ap 0x%lx\n", base);
+ while (new_base != (base + PAGE_SIZE)) {
+
+ ret = rsi_mem_set_perm_index(new_base, base + PAGE_SIZE,
+ perm_index, new_cookie, &new_base,
+ &response, &new_cookie);
+
+ if (ret != RSI_SUCCESS || response == RSI_REJECT) {
+ ERROR("rsi_mem_set_perm_index failed 0x%lx\n", new_base);
+ return PSI_RETURN_TO_P0;
+ }
+ }
+
+ restore_plane_context(run);
+ return PSI_RETURN_TO_PN;
+ }
+
/* Disallow SMC from Plane N */
if (ec == EC_AARCH64_SMC) {
+ /* TODO Support PSCI in future */
restore_plane_context(run);
run->enter.gprs[0] = RSI_ERROR_STATE;
- return true;
+ return PSI_RETURN_TO_PN;
}
/* Handle PSI HVC call from Plane N */
@@ -90,22 +117,22 @@
case PSI_CALL_GET_SHARED_BUFF_CMD:
run->enter.gprs[0] = RSI_SUCCESS;
run->enter.gprs[1] = (u_register_t)realm_get_my_shared_structure();
- return true;
+ return PSI_RETURN_TO_PN;
case PSI_CALL_GET_PLANE_ID_CMD:
run->enter.gprs[0] = RSI_SUCCESS;
run->enter.gprs[1] = plane_index;
- return true;
+ return PSI_RETURN_TO_PN;
case PSI_CALL_EXIT_PRINT_CMD:
/* exit to host to flush buffer, then return to PN */
ret = realm_exit_to_host_as_plane_n(HOST_CALL_EXIT_PRINT_CMD, plane_index);
run->enter.gprs[0] = ret;
- return true;
+ return PSI_RETURN_TO_PN;
case PSI_P0_CALL:
default:
- return false;
+ return PSI_RETURN_TO_P0;
}
}
- return false;
+ return PSI_RETURN_TO_P0;
}
static bool plane_common_init(u_register_t plane_index,
@@ -143,7 +170,7 @@
run->enter.flags = flags;
- while (ret1) {
+ while (true) {
ret = rsi_plane_enter(plane_index, (u_register_t)run);
if (ret != RSI_SUCCESS) {
ERROR("Plane %u enter failed ret= 0x%lx\n", plane_index, ret);
@@ -156,8 +183,11 @@
run->exit.hpfar,
run->exit.far);
- ret1 = handle_plane_exit(plane_index, perm_index, run);
+ ret = handle_plane_exit(plane_index, perm_index, run);
+
+ if (ret != PSI_RETURN_TO_PN) {
+ return true;
+ }
}
- return true;
}