summaryrefslogtreecommitdiff
path: root/spm
diff options
context:
space:
mode:
authorMadhukar Pappireddy <madhukar.pappireddy@arm.com>2022-09-19 13:48:13 -0500
committerMadhukar Pappireddy <madhukar.pappireddy@arm.com>2022-10-04 15:01:22 -0500
commit92d2e814ee0638d3af2141bc4148d5bace6d456e (patch)
treedc70da03e74ba105158fb574b58f94d55c1806f6 /spm
parent0b0ca11f7cfc0f9f9f6dfb42f9b6ec201f746550 (diff)
fix(interrupts): deny new direct request message from endpoint
Please refer to detailed description in the comment preceding the helper function introduced in cactus_interrupt.c file. Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com> Change-Id: Ie70d68514dac44211767d611db6d84991a8b48c6
Diffstat (limited to 'spm')
-rw-r--r--spm/cactus/cactus_interrupt.c46
-rw-r--r--spm/cactus/cactus_tests/cactus_test_interrupts.c4
2 files changed, 44 insertions, 6 deletions
diff --git a/spm/cactus/cactus_interrupt.c b/spm/cactus/cactus_interrupt.c
index 35fdf30..16785db 100644
--- a/spm/cactus/cactus_interrupt.c
+++ b/spm/cactus/cactus_interrupt.c
@@ -59,6 +59,46 @@ static void post_interrupt_handler(uint32_t intid)
spin_unlock(&sp_handler_lock[intid]);
}
+/*
+ * Cactus SP does not implement application threads. Hence, once the Cactus SP
+ * sends the managed exit response to the direct request originator, execution
+ * is still frozen in interrupt handler context.
+ * Though it moves to WAITING state, it is not able to accept new direct request
+ * message from any endpoint. It can only receive a direct request message with
+ * the command CACTUS_RESUME_AFTER_MANAGED_EXIT from the originator of the
+ * suspended direct request message in order to return from the interrupt
+ * handler context and resume the processing of suspended request.
+ */
+void send_managed_exit_response(void)
+{
+ struct ffa_value ffa_ret;
+ bool waiting_resume_after_managed_exit;
+
+ /* Send managed exit response. */
+ ffa_ret = cactus_response(g_ffa_id, g_dir_req_source_id,
+ MANAGED_EXIT_INTERRUPT_ID);
+ waiting_resume_after_managed_exit = true;
+
+ while (waiting_resume_after_managed_exit) {
+
+ waiting_resume_after_managed_exit =
+ (ffa_func_id(ffa_ret) != FFA_MSG_SEND_DIRECT_REQ_SMC32 &&
+ ffa_func_id(ffa_ret) != FFA_MSG_SEND_DIRECT_REQ_SMC64) ||
+ ffa_dir_msg_source(ffa_ret) != g_dir_req_source_id ||
+ cactus_get_cmd(ffa_ret) != CACTUS_RESUME_AFTER_MANAGED_EXIT;
+
+ if (waiting_resume_after_managed_exit) {
+ ERROR("Expected a direct message request from endpoint"
+ " %x with command CACTUS_RESUME_AFTER_MANAGED_EXIT\n",
+ g_dir_req_source_id);
+ ffa_ret = cactus_error_resp(g_ffa_id,
+ ffa_dir_msg_source(ffa_ret),
+ CACTUS_ERROR_TEST);
+ }
+ }
+ VERBOSE("Resuming the suspended command\n");
+}
+
void cactus_interrupt_handler_irq(void)
{
uint32_t intid = spm_interrupt_get();
@@ -72,8 +112,7 @@ void cactus_interrupt_handler_irq(void)
*/
VERBOSE("vIRQ: Sending ME response to %x\n",
g_dir_req_source_id);
- cactus_response(g_ffa_id, g_dir_req_source_id,
- managed_exit_interrupt_id);
+ send_managed_exit_response();
} else {
switch (intid) {
case IRQ_TWDOG_INTID:
@@ -114,8 +153,7 @@ void cactus_interrupt_handler_fiq(void)
*/
VERBOSE("vFIQ: Sending ME response to %x\n",
g_dir_req_source_id);
- cactus_response(g_ffa_id, g_dir_req_source_id,
- MANAGED_EXIT_INTERRUPT_ID);
+ send_managed_exit_response();
break;
default:
/*
diff --git a/spm/cactus/cactus_tests/cactus_test_interrupts.c b/spm/cactus/cactus_tests/cactus_test_interrupts.c
index c438050..7f3de0c 100644
--- a/spm/cactus/cactus_tests/cactus_test_interrupts.c
+++ b/spm/cactus/cactus_tests/cactus_test_interrupts.c
@@ -82,8 +82,8 @@ CACTUS_CMD_HANDLER(sleep_fwd_cmd, CACTUS_FWD_SLEEP_CMD)
*/
VERBOSE("SP%x: received Managed Exit as response\n",
vm_id);
- ffa_ret = ffa_msg_send_direct_req64(vm_id, fwd_dest,
- 0, 0, 0, 0, 0);
+ ffa_ret = cactus_resume_after_managed_exit(vm_id,
+ fwd_dest);
}
}