feat(interrupts): intercept S-EL0 SP direct response message

Since FF-A v1.1 EAC0 spec only allows signaling a virtual secure
interrupt to an S-EL0 SP when in WAITING state, SPMC intercepts
a direct response message from the S-EL0 partition to proactively
signal the pending virtual secure interrupt and resume the vCPU
of the S-EL0 partition.

Further, once the secure interrupt is handled, SPMC resumes the
direct response message from current S-EL0 partition and takes
care of unwinding the call chain.

Change-Id: I55da462b5b6b7813f09a7b57c16fcd378972ac3a
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
diff --git a/inc/hf/api.h b/inc/hf/api.h
index 929fe52..9c9b386 100644
--- a/inc/hf/api.h
+++ b/inc/hf/api.h
@@ -133,3 +133,8 @@
 
 struct ffa_value api_ffa_console_log(const struct ffa_value args,
 				     struct vcpu *current);
+
+void api_ffa_resume_direct_resp_target(struct vcpu *current, struct vcpu **next,
+				       ffa_vm_id_t receiver_vm_id,
+				       struct ffa_value to_ret,
+				       bool is_nwd_call_chain);
diff --git a/inc/hf/arch/plat/ffa.h b/inc/hf/arch/plat/ffa.h
index a530af1..1154587 100644
--- a/inc/hf/arch/plat/ffa.h
+++ b/inc/hf/arch/plat/ffa.h
@@ -330,3 +330,8 @@
 struct ffa_value plat_ffa_other_world_mem_reclaim(
 	struct vm *to, ffa_memory_handle_t handle,
 	ffa_memory_region_flags_t flags, struct mpool *page_pool);
+
+bool plat_ffa_intercept_direct_response(struct vcpu_locked current_locked,
+					struct vcpu **next,
+					struct ffa_value to_ret,
+					struct ffa_value *signal_interrupt);
diff --git a/inc/hf/vcpu.h b/inc/hf/vcpu.h
index 1395bcd..179863f 100644
--- a/inc/hf/vcpu.h
+++ b/inc/hf/vcpu.h
@@ -200,6 +200,15 @@
 
 	/** Partition Runtime Model. */
 	enum partition_runtime_model rt_model;
+
+	/**
+	 * Direct response message has been intercepted to handle virtual
+	 * secure interrupt for a S-EL0 partition.
+	 */
+	bool direct_resp_intercepted;
+
+	/** Save direct response message args to be resumed later. */
+	struct ffa_value direct_resp_ffa_value;
 };
 
 /** Encapsulates a vCPU whose lock is held. */