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;