feat(interrupts): allow interrupt to be enabled or disabled in runtime
This patch extends the paravirtualized interface introduced in earlier
patches to either enable or disable a secure physical interrupt.
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
Change-Id: I86250d8e4788feae4d2b9898567c640aa54b710f
diff --git a/src/arch/aarch64/plat/ffa/spmc.c b/src/arch/aarch64/plat/ffa/spmc.c
index aca307b..a197256 100644
--- a/src/arch/aarch64/plat/ffa/spmc.c
+++ b/src/arch/aarch64/plat/ffa/spmc.c
@@ -2778,6 +2778,7 @@
* partition:
* - Change the target CPU of the interrupt.
* - Change the security state of the interrupt.
+ * - Enable or disable the physical interrupt.
*/
int64_t plat_ffa_interrupt_reconfigure(uint32_t int_id, uint32_t command,
uint32_t value, struct vcpu *current)
@@ -2832,6 +2833,19 @@
}
int_desc = vm_interrupt_set_sec_state(vm_locked, int_id, value);
break;
+ case INT_RECONFIGURE_ENABLE:
+ /* Enable or disable the interrupt. */
+ if (value != INT_DISABLE && value != INT_ENABLE) {
+ dlog_verbose(
+ "Illegal value %x specified while "
+ "reconfiguring interrupt %x\n",
+ value, int_id);
+ goto out_unlock;
+ } else {
+ int_desc = vm_interrupt_set_enable(vm_locked, int_id,
+ value == INT_ENABLE);
+ }
+ break;
default:
dlog_verbose("Interrupt reconfigure: Unsupported command %x\n",
command);
diff --git a/src/load.c b/src/load.c
index 1c1794d..ae97a2d 100644
--- a/src/load.c
+++ b/src/load.c
@@ -151,6 +151,7 @@
}
interrupt_desc_set_valid(int_desc, true);
+ interrupt_desc_set_enabled(int_desc, true);
}
/**
@@ -184,6 +185,7 @@
interrupt = dev_region.interrupts[j];
infer_interrupt(interrupt, &int_desc);
vm_locked.vm->interrupt_desc[k] = int_desc;
+ assert(int_desc.enabled);
/*
* Configure the physical interrupts allocated for this
diff --git a/src/vm.c b/src/vm.c
index ec1e374..8a91a2b 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -1041,3 +1041,20 @@
return int_desc;
}
+
+/**
+ * Enable or disable the specified interrupt id belonging to specified vm.
+ */
+struct interrupt_descriptor *vm_interrupt_set_enable(struct vm_locked vm_locked,
+ uint32_t id, bool enable)
+{
+ struct interrupt_descriptor *int_desc;
+
+ int_desc = vm_find_interrupt_descriptor(vm_locked, id);
+
+ if (int_desc != NULL) {
+ interrupt_desc_set_enabled(int_desc, enable);
+ }
+
+ return int_desc;
+}