fix(ipi): fix deadlock in IPI handler
There is a potential deadlock in the IPI interrupt
handler where the function attempts to grab the vcpu
lock on the current CPU which is already locked
from the caller.
Tested with a Trusty SP and Hafnium at sEL2.
Change-Id: Ib82652564da02ce15b7a0fa259153860a5721963
Signed-off-by: Andrei Homescu <ahomescu@xwf.google.com>
diff --git a/src/hf_ipi.c b/src/hf_ipi.c
index be740a2..c630026 100644
--- a/src/hf_ipi.c
+++ b/src/hf_ipi.c
@@ -244,6 +244,7 @@
{
enum ipi_sri_action ipi_sri_action = IPI_SRI_ACTION_INIT;
bool ret = true;
+ struct vcpu* current = target_vcpu_locked.vcpu;
ret = hf_ipi_handle_list_element(target_vcpu_locked, &ipi_sri_action);
@@ -251,13 +252,14 @@
* Clear the pending ipi list, handling the ipi for the remaining
* target vCPUs.
*/
- for (struct vcpu *target_vcpu =
- hf_ipi_get_pending_target_vcpu(target_vcpu_locked.vcpu);
+ for (struct vcpu* target_vcpu = hf_ipi_get_pending_target_vcpu(current);
target_vcpu != NULL;
target_vcpu = hf_ipi_get_pending_target_vcpu(target_vcpu)) {
- target_vcpu_locked = vcpu_lock(target_vcpu);
+ if (target_vcpu != current)
+ target_vcpu_locked = vcpu_lock(target_vcpu);
hf_ipi_handle_list_element(target_vcpu_locked, &ipi_sri_action);
- vcpu_unlock(&target_vcpu_locked);
+ if (target_vcpu != current)
+ vcpu_unlock(&target_vcpu_locked);
}
return ret;