fix(ipi): small fixes to the ipi implementation

- Fix the return type for the api_hf_interrupt_send_ipi function. In
the case the target vcpu id is not valid it returns -1 so the type
must be signed.
- Fix the cast in the hf_call in hf_interrupt_send_ipi, the arguments
for this function are uint64_t so cast to this.
- Move hf_ipi_init_interrupt to arch_cpu_init as this is a more
appropriate place for it.
- Lock the cpu when setting and getting the target vCPU with
pending IPI.
- Set the IPI and SRI interrupts to enabled during initialization.

Signed-off-by: Daniel Boulby <daniel.boulby@arm.com>
Change-Id: I81ca43f767a7bfeb803f65b40f8be403daecfa80
diff --git a/inc/hf/api.h b/inc/hf/api.h
index 900a2ce..bc5bedf 100644
--- a/inc/hf/api.h
+++ b/inc/hf/api.h
@@ -49,8 +49,8 @@
 				    uint32_t intid,
 				    struct vcpu_locked current_locked,
 				    struct vcpu **next);
-uint64_t api_hf_interrupt_send_ipi(uint32_t target_vcpu_id,
-				   struct vcpu *current);
+int64_t api_hf_interrupt_send_ipi(uint32_t target_vcpu_id,
+				  struct vcpu *current);
 
 struct ffa_value api_ffa_msg_send(ffa_id_t sender_vm_id,
 				  ffa_id_t receiver_vm_id, uint32_t size,
diff --git a/inc/vmapi/hf/call.h b/inc/vmapi/hf/call.h
index 5f198ce..2f5fd6f 100644
--- a/inc/vmapi/hf/call.h
+++ b/inc/vmapi/hf/call.h
@@ -412,7 +412,7 @@
  */
 static inline int64_t hf_interrupt_send_ipi(ffa_vcpu_index_t target_vcpu_id)
 {
-	return hf_call(HF_INTERRUPT_SEND_IPI, (uint32_t)target_vcpu_id, 0, 0);
+	return hf_call(HF_INTERRUPT_SEND_IPI, (uint64_t)target_vcpu_id, 0, 0);
 }
 
 /** Obtains the Hafnium's version of the implemented FF-A specification. */
diff --git a/src/api.c b/src/api.c
index 2e4d492..957cabe 100644
--- a/src/api.c
+++ b/src/api.c
@@ -4921,13 +4921,12 @@
  * Send an IPI interrupt to a target vcpu belonging to the
  * sender that isn't itself.
  */
-uint64_t api_hf_interrupt_send_ipi(uint32_t target_vcpu_id,
-				   struct vcpu *current)
+int64_t api_hf_interrupt_send_ipi(uint32_t target_vcpu_id, struct vcpu *current)
 {
 	struct vm *vm = current->vm;
 	ffa_vcpu_index_t target_vcpu_index = vcpu_id_to_index(target_vcpu_id);
 
-	if (target_vcpu_index >= vm->vcpu_count &&
+	if (target_vcpu_index >= vm->vcpu_count ||
 	    target_vcpu_index == cpu_index(current->cpu)) {
 		dlog_verbose("Invalid vCPU %d for IPI.\n", target_vcpu_id);
 		return -1;
diff --git a/src/arch/aarch64/hypervisor/cpu.c b/src/arch/aarch64/hypervisor/cpu.c
index 13024aa..378f1a6 100644
--- a/src/arch/aarch64/hypervisor/cpu.c
+++ b/src/arch/aarch64/hypervisor/cpu.c
@@ -19,6 +19,7 @@
 #include "hf/addr.h"
 #include "hf/check.h"
 #include "hf/ffa.h"
+#include "hf/hf_ipi.h"
 #include "hf/plat/interrupts.h"
 #include "hf/std.h"
 #include "hf/vm.h"
@@ -323,6 +324,9 @@
 	 * running core.
 	 */
 	host_timer_init();
+
+	/* Initialise IPIs for the current cpu. */
+	hf_ipi_init_interrupt();
 }
 
 struct vcpu *arch_vcpu_resume(struct cpu *c)
diff --git a/src/arch/aarch64/plat/ffa/spmc.c b/src/arch/aarch64/plat/ffa/spmc.c
index f1f66cb..105aa93 100644
--- a/src/arch/aarch64/plat/ffa/spmc.c
+++ b/src/arch/aarch64/plat/ffa/spmc.c
@@ -2058,6 +2058,7 @@
 		.sec_state = INT_DESC_SEC_STATE_NS,
 		.priority = SRI_PRIORITY,
 		.valid = true,
+		.enabled = true,
 	};
 
 	/* TODO: when supported, make the interrupt driver use cpu structure. */
diff --git a/src/arch/aarch64/plat/psci/spmc.c b/src/arch/aarch64/plat/psci/spmc.c
index 18f910b..7f9fb01 100644
--- a/src/arch/aarch64/plat/psci/spmc.c
+++ b/src/arch/aarch64/plat/psci/spmc.c
@@ -13,7 +13,6 @@
 #include "hf/check.h"
 #include "hf/cpu.h"
 #include "hf/dlog.h"
-#include "hf/hf_ipi.h"
 #include "hf/vm.h"
 
 #include "vmapi/hf/types.h"
@@ -75,8 +74,6 @@
 
 	arch_cpu_init(c);
 
-	/* Initialize IPI for running core. */
-	hf_ipi_init_interrupt();
 	/* Initialize SRI for running core. */
 	plat_ffa_sri_init(c);
 
diff --git a/src/hf_ipi.c b/src/hf_ipi.c
index f227ece..3702b49 100644
--- a/src/hf_ipi.c
+++ b/src/hf_ipi.c
@@ -28,6 +28,7 @@
 		.sec_state = INT_DESC_SEC_STATE_S,
 		.priority = IPI_PRIORITY,
 		.valid = true,
+		.enabled = true,
 	};
 
 	plat_interrupts_configure_interrupt(ipi_desc);
@@ -39,9 +40,16 @@
  */
 struct vcpu *hf_ipi_get_pending_target_vcpu(struct cpu *current)
 {
-	struct vcpu *ret = current->ipi_target_vcpu;
+	struct vcpu *ret;
+
+	sl_lock(&current->lock);
+
+	ret = current->ipi_target_vcpu;
 
 	current->ipi_target_vcpu = NULL;
+
+	sl_unlock(&current->lock);
+
 	return ret;
 }
 
@@ -53,7 +61,11 @@
 	struct vcpu *target_vcpu = vm_get_vcpu(vm, target_vcpu_index);
 	struct cpu *target_cpu = target_vcpu->cpu;
 
+	sl_lock(&target_cpu->lock);
+
 	target_cpu->ipi_target_vcpu = target_vcpu;
+
+	sl_unlock(&target_cpu->lock);
 	plat_interrupts_send_sgi(HF_IPI_INTID, target_cpu, true);
 }