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(¤t->lock);
+
+ ret = current->ipi_target_vcpu;
current->ipi_target_vcpu = NULL;
+
+ sl_unlock(¤t->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);
}