feat(interrupts): resume interrupted target vCPU
An SP could be interrupted by a NS interrupt whilst handling a direct
message request from another SP. The target SP could send a managed
exit response, if supported.
Consequently, the sender of the direct message request resumes the
target SP by allocating CPU cycles using dummy direct message request.
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
Change-Id: I697aeb189da12850af9a1db4c3e3e550b5b36541
diff --git a/spm/cactus/cactus_tests/cactus_test_interrupts.c b/spm/cactus/cactus_tests/cactus_test_interrupts.c
index 31ba7ca..13a5e59 100644
--- a/spm/cactus/cactus_tests/cactus_test_interrupts.c
+++ b/spm/cactus/cactus_tests/cactus_test_interrupts.c
@@ -54,12 +54,34 @@
ffa_ret = cactus_sleep_cmd(vm_id, fwd_dest, sleep_ms);
- while (ffa_func_id(ffa_ret) == FFA_INTERRUPT) {
- /* Received FFA_INTERRUPT in blocked state. */
- VERBOSE("Processing FFA_INTERRUPT while blocked on direct response\n");
- unsigned int my_core_pos = platform_get_core_pos(read_mpidr_el1());
+ /*
+ * The target of the direct request could be pre-empted any number of
+ * times. Moreover, the target SP may or may not support managed exit.
+ * Hence, the target is allocated cpu cycles in this while loop.
+ */
+ while ((ffa_func_id(ffa_ret) == FFA_INTERRUPT) ||
+ is_expected_cactus_response(ffa_ret, MANAGED_EXIT_INTERRUPT_ID,
+ 0)) {
- ffa_ret = ffa_run(fwd_dest, my_core_pos);
+ if (ffa_func_id(ffa_ret) == FFA_INTERRUPT) {
+ /* Received FFA_INTERRUPT in blocked state. */
+ VERBOSE("Processing FFA_INTERRUPT while"
+ " blocked on direct response\n");
+ unsigned int my_core_pos =
+ platform_get_core_pos(read_mpidr_el1());
+
+ ffa_ret = ffa_run(fwd_dest, my_core_pos);
+ } else {
+ /*
+ * Destination sent managed exit response. Allocate
+ * dummy cycles through direct request message to
+ * destination SP.
+ */
+ 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);
+ }
}
if (!is_ffa_direct_response(ffa_ret)) {
@@ -68,7 +90,7 @@
CACTUS_ERROR_FFA_CALL);
}
- if (cactus_get_response(ffa_ret) != sleep_ms) {
+ if (cactus_get_response(ffa_ret) < sleep_ms) {
ERROR("Request returned: %u ms!\n",
cactus_get_response(ffa_ret));
return cactus_error_resp(vm_id, ffa_dir_msg_source(*args),