feat(interrupts): modify interrupt properties in runtime
At present, the 'reconfigure interrupt' paravirtualized interface only
allows to change the sec state, and the target CPU of the interrupt.
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
Change-Id: Ie8780b6854314754ad948723d77c8dba68ae0c00
diff --git a/inc/hf/interrupt_desc.h b/inc/hf/interrupt_desc.h
index 0780dcc..815816e 100644
--- a/inc/hf/interrupt_desc.h
+++ b/inc/hf/interrupt_desc.h
@@ -50,6 +50,13 @@
bitmap->bitmap[index] &= ~(1U << shift);
}
+
+/**
+ * Legal values to change the security state of an interrupt.
+ */
+#define INT_SEC_STATE_NS 0
+#define INT_SEC_STATE_S 1
+
/**
* Attributes encoding in the manifest:
diff --git a/inc/hf/vm.h b/inc/hf/vm.h
index 0ab4aaa..3f06d38 100644
--- a/inc/hf/vm.h
+++ b/inc/hf/vm.h
@@ -395,8 +395,6 @@
(UINT32_C(1) << VM_POWER_MANAGEMENT_CPU_OFF_SHIFT)) != 0;
}
-struct interrupt_descriptor *vm_find_interrupt_descriptor(
- struct vm_locked vm_locked, uint32_t id);
struct interrupt_descriptor *vm_interrupt_set_target_mpidr(
struct vm_locked vm_locked, uint32_t id, uint32_t target_mpidr);
struct interrupt_descriptor *vm_interrupt_set_sec_state(
diff --git a/inc/vmapi/hf/abi.h b/inc/vmapi/hf/abi.h
index dd9e698..9a078d4 100644
--- a/inc/vmapi/hf/abi.h
+++ b/inc/vmapi/hf/abi.h
@@ -26,4 +26,8 @@
/* Custom FF-A-like calls returned from FFA_RUN. */
#define HF_FFA_RUN_WAIT_FOR_INTERRUPT 0xff06
+/* Possible commands that reconfigure an interrupt. */
+#define INT_RECONFIGURE_TARGET_PE 0
+#define INT_RECONFIGURE_SEC_STATE 1
+
/* clang-format on */
diff --git a/src/arch/aarch64/plat/ffa/spmc.c b/src/arch/aarch64/plat/ffa/spmc.c
index 59bd11c..aca307b 100644
--- a/src/arch/aarch64/plat/ffa/spmc.c
+++ b/src/arch/aarch64/plat/ffa/spmc.c
@@ -2773,6 +2773,11 @@
/**
* Reconfigure the interrupt belonging to the current partition at runtime.
+ * At present, this paravirtualized interface only allows the following
+ * commands which signify what change is being requested by the current
+ * partition:
+ * - Change the target CPU of the interrupt.
+ * - Change the security state of the interrupt.
*/
int64_t plat_ffa_interrupt_reconfigure(uint32_t int_id, uint32_t command,
uint32_t value, struct vcpu *current)
@@ -2780,7 +2785,7 @@
struct vm *vm = current->vm;
struct vm_locked vm_locked;
int64_t ret = -1;
- struct interrupt_descriptor *int_desc;
+ struct interrupt_descriptor *int_desc = NULL;
/*
* Lock VM to protect interrupt descriptor from being modified
@@ -2788,9 +2793,52 @@
*/
vm_locked = vm_lock(vm);
- /* Check if the interrupt belongs to the current SP. */
- int_desc = vm_find_interrupt_descriptor(vm_locked, int_id);
+ switch (command) {
+ case INT_RECONFIGURE_TARGET_PE:
+ /* Here, value represents the target PE index. */
+ if (value >= MAX_CPUS) {
+ dlog_verbose(
+ "Illegal target PE index specified while "
+ "reconfiguring interrupt %x\n",
+ int_id);
+ goto out_unlock;
+ }
+ /*
+ * An UP SP cannot reconfigure an interrupt to be targetted to
+ * any other physical CPU except the one it is currently
+ * running on.
+ */
+ if ((vm->vcpu_count == 1) &&
+ (value != cpu_index(current->cpu))) {
+ dlog_verbose(
+ "Illegal target PE index specified by current "
+ "UP SP\n");
+ goto out_unlock;
+ }
+
+ /* Configure the interrupt to be routed to a specific CPU. */
+ int_desc = vm_interrupt_set_target_mpidr(
+ vm_locked, int_id, cpu_find_index(value)->id);
+ break;
+ case INT_RECONFIGURE_SEC_STATE:
+ /* Specify the new security state of the interrupt. */
+ if (value != INT_SEC_STATE_NS && value != INT_SEC_STATE_S) {
+ dlog_verbose(
+ "Illegal value %x specified while "
+ "reconfiguring interrupt %x\n",
+ value, int_id);
+ goto out_unlock;
+ }
+ int_desc = vm_interrupt_set_sec_state(vm_locked, int_id, value);
+ break;
+ default:
+ dlog_verbose("Interrupt reconfigure: Unsupported command %x\n",
+ command);
+ goto out_unlock;
+ }
+
+ /* Check if the interrupt belongs to the current SP. */
if (int_desc == NULL) {
dlog_verbose("Interrupt %x does not belong to current SP\n",
int_id);
diff --git a/src/vm.c b/src/vm.c
index 1b7ae9d..ec1e374 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -988,7 +988,7 @@
* Obtain the interrupt descriptor entry of the specified vm corresponding
* to the specific interrupt id.
*/
-struct interrupt_descriptor *vm_find_interrupt_descriptor(
+static struct interrupt_descriptor *vm_find_interrupt_descriptor(
struct vm_locked vm_locked, uint32_t id)
{
for (uint32_t i = 0; i < HF_NUM_INTIDS; i++) {