feat(ipi): handle in VCPU_STATE_BLOCKED/PREEMPTED

If the target vCPU is in either VCPU_STATE_BLOCKED or
VCPU_STATE_PREEMPTED the SPMC will simply queue the interrupt.
The next time the SP is executed, the SPMC will pend the HCR_EL2.VI
virtual interrupt lines, and the SP will be able to handle the IPI.

Signed-off-by: J-Alves <joao.alves@arm.com>
Change-Id: I21b1260706b5626b0e0b2386b9d0fa76d26cc1c1
diff --git a/src/hf_ipi.c b/src/hf_ipi.c
index 3702b49..3aa58e6 100644
--- a/src/hf_ipi.c
+++ b/src/hf_ipi.c
@@ -71,11 +71,12 @@
 
 /**
  * IPI IRQ specific handling for the secure interrupt for each vCPU state:
- *   - RUNNING: Continue secure interrupt handling as normal, injecting
- *   a virtual interrupt to the vCPU.
- *   - WAITING: Mark the IPI as complete from the SPMC perspective and
- *   trigger an SRI so the NWd can schedule to target vCPU to run.
- *   - Other states are not currently supported so exit the handler.
+ *   - WAITING: Trigger an SRI so the NWd can schedule to target vCPU to run.
+ *   - RUNNING:
+ *   - PREEMPTED/BLOCKED: Return and allow the normal secure interrupt handling
+ *   to handle the interrupt as usual.
+ * For all cases we must also mark the interrupt as complete from the
+ * SPMC perspective.
  * Returns True if the IPI SGI has been handled.
  * False if further secure interrupt handling is required.
  */
@@ -84,16 +85,21 @@
 	struct vcpu *target_vcpu = target_vcpu_locked.vcpu;
 
 	switch (target_vcpu->state) {
-	case VCPU_STATE_RUNNING:
-		return false;
 	case VCPU_STATE_WAITING:
 		plat_ffa_sri_trigger_not_delayed(target_vcpu->cpu);
 		return true;
+	case VCPU_STATE_RUNNING:
+	case VCPU_STATE_BLOCKED:
+	case VCPU_STATE_PREEMPTED:
+		/*
+		 * Let the normal secure interrupt handling handle the
+		 * interrupt as usual.
+		 */
+		return false;
 	default:
-		dlog_verbose(
-			"IPIs not currently supported for when the target_vcpu "
-			"is in the state %d\n",
-			target_vcpu->state);
+		dlog_error("Unexpected state: %u handling an IPI for [%x %u]",
+			   target_vcpu->state, target_vcpu->vm->id,
+			   vcpu_index(target_vcpu));
 		return true;
 	}
 }