feat(ffa): resume execution after interrupt completion
This patch adds plat_ffa_normal_world_resume() function that invokes
FFA_NORMAL_WORLD_RESUME ABI to request SPMD to resume execution
of normal world on current PE.
This patch also adds plat_ffa_preempted_vcpu_resume() helper function
that resumes a SP on current PE if SP was pre-empted by a secure
interrupt.
Moreover, this patch also performs many CHECKS related to secure
interrupt handling.
Change-Id: Ia7d5bd5b2ca4bdf1a29b73031ca6efc8563aaf36
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
diff --git a/src/api.c b/src/api.c
index d73f330..8feb745 100644
--- a/src/api.c
+++ b/src/api.c
@@ -2057,6 +2057,14 @@
return ffa_error(FFA_DENIED);
}
+ /*
+ * Per FF-A v1.1 Beta section 8.4.1.2 bullet 6, SPMC can signal
+ * a secure interrupt to a SP that is performing managed exit.
+ * We have taken a implementation defined choice to not allow
+ * Managed exit while a SP is processing a secure interrupt.
+ */
+ CHECK(!current->processing_secure_interrupt);
+
plat_interrupts_set_priority_mask(0xff);
current->processing_managed_exit = false;
} else {
@@ -2073,10 +2081,34 @@
return ffa_error(FFA_DENIED);
}
+ /* Refer to FF-A v1.1 Beta0 section 7.3 bulet 3. */
if (current->direct_request_origin_vm_id != receiver_vm_id) {
vcpu_unlock(¤t_locked);
return ffa_error(FFA_DENIED);
}
+
+ /*
+ * Per FF-A v1.1 Beta0 section 7.4, if a secure interrupt is
+ * handled by an SP in RUNNING state the existing runtime model
+ * is preserved. Hence, per section 7.3 bullet 3, SP can use
+ * FFA_MSG_SEND_DIRECT_RESP to return a response after
+ * interrupt completion.
+ */
+ if (current->processing_secure_interrupt) {
+ /* There is no preempted vCPU to resume. */
+ CHECK(current->preempted_vcpu == NULL);
+
+ /* Unmask interrupts. */
+ plat_interrupts_set_priority_mask(0xff);
+
+ /*
+ * Clear fields corresponding to secure interrupt
+ * handling.
+ */
+ current->processing_secure_interrupt = false;
+ current->secure_interrupt_deactivated = false;
+ current->current_sec_interrupt_id = 0;
+ }
}
/* Clear direct request origin for the caller. */