feat(ipi): introduce IPI paravirtualised interface
Interprocessor Interrupts (IPIs) allow an SP to send an interrupt to
itself on another CPU. This patch starts the implementation of this
feature and enables it for the case where the SP is in the RUNNING
state on the target_vcpu.
Signed-off-by: Daniel Boulby <daniel.boulby@arm.com>
Change-Id: Idd0e1a5863730ae0f169bd0f56ac3abcd2916870
diff --git a/src/api.c b/src/api.c
index 5bac913..ed7f772 100644
--- a/src/api.c
+++ b/src/api.c
@@ -23,6 +23,7 @@
#include "hf/ffa_internal.h"
#include "hf/ffa_memory.h"
#include "hf/ffa_v1_0.h"
+#include "hf/hf_ipi.h"
#include "hf/mm.h"
#include "hf/plat/console.h"
#include "hf/plat/interrupts.h"
@@ -2250,6 +2251,7 @@
* - NPI
* - ME
* - Virtual Timer.
+ * - IPI
*
* These are VIs with no expected interrupt descriptor.
*/
@@ -2257,7 +2259,7 @@
{
return intid == HF_NOTIFICATION_PENDING_INTID ||
intid == HF_MANAGED_EXIT_INTID ||
- intid == HF_VIRTUAL_TIMER_INTID;
+ intid == HF_VIRTUAL_TIMER_INTID || intid == HF_IPI_INTID;
}
/**
@@ -4851,3 +4853,27 @@
vcpu_unlock(&vcpu_locked);
return (struct ffa_value){.func = FFA_SUCCESS_32};
}
+
+/**
+ * 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)
+{
+ 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 &&
+ target_vcpu_index == cpu_index(current->cpu)) {
+ dlog_verbose("Invalid vCPU %d for IPI.\n", target_vcpu_id);
+ return -1;
+ }
+
+ dlog_verbose("Injecting IPI to target vCPU%d for %#x\n", target_vcpu_id,
+ vm->id);
+
+ hf_ipi_send_interrupt(vm, target_vcpu_index);
+
+ return 0;
+}