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;
}
}