feat: reclaim all resources from an aborted SP
Once any execution context of an SP is aborted, all the resources of
the SP are reclaimed by SPMC. This patch creates a placeholder
function to this effect which can be populated with necessary actions
such as disabling all interrupts belonging to the SP.
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
Change-Id: Ia4c2913ad0aeda21770052ca748d41734cafd8b4
diff --git a/src/api.c b/src/api.c
index 210c604..843b8dc 100644
--- a/src/api.c
+++ b/src/api.c
@@ -385,6 +385,7 @@
struct ffa_value ret = ffa_error(FFA_ABORTED);
struct vcpu_locked current_locked;
struct vcpu *next;
+ struct vm_locked vm_locked;
dlog_notice("Aborting VM %#x vCPU %u\n", current->vm->id,
vcpu_index(current));
@@ -399,7 +400,9 @@
atomic_store_explicit(¤t->vm->aborting, true,
memory_order_relaxed);
- /* TODO: free resources once all vCPUs abort. */
+ vm_locked = vm_lock(current->vm);
+ plat_ffa_free_vm_resources(vm_locked);
+ vm_unlock(&vm_locked);
current_locked = vcpu_lock(current);
next = api_switch_to_primary(current_locked, ret, VCPU_STATE_ABORTED);
diff --git a/src/arch/aarch64/plat/ffa/absent.c b/src/arch/aarch64/plat/ffa/absent.c
index 0e300c8..b1c34c5 100644
--- a/src/arch/aarch64/plat/ffa/absent.c
+++ b/src/arch/aarch64/plat/ffa/absent.c
@@ -639,3 +639,8 @@
(void)current;
return -1;
}
+
+void plat_ffa_free_vm_resources(struct vm_locked vm_locked)
+{
+ (void)vm_locked;
+}
diff --git a/src/arch/aarch64/plat/ffa/hypervisor.c b/src/arch/aarch64/plat/ffa/hypervisor.c
index c80458d..a3d2ce5 100644
--- a/src/arch/aarch64/plat/ffa/hypervisor.c
+++ b/src/arch/aarch64/plat/ffa/hypervisor.c
@@ -2233,3 +2233,8 @@
return waiting_vm->id;
}
+
+void plat_ffa_free_vm_resources(struct vm_locked vm_locked)
+{
+ (void)vm_locked;
+}
diff --git a/src/arch/aarch64/plat/ffa/spmc.c b/src/arch/aarch64/plat/ffa/spmc.c
index a3d379a..7f52efd 100644
--- a/src/arch/aarch64/plat/ffa/spmc.c
+++ b/src/arch/aarch64/plat/ffa/spmc.c
@@ -1323,6 +1323,25 @@
return 0;
}
+static void plat_ffa_disable_vm_interrupts(struct vm_locked vm_locked)
+{
+ uint32_t core_pos = arch_find_core_pos();
+
+ /* Gracefully disable interrupts. */
+ dlog_verbose("Interrupts belonging to SP %x disabled\n",
+ vm_locked.vm->id);
+
+ for (uint32_t i = 0; i < HF_NUM_INTIDS; i++) {
+ struct interrupt_descriptor int_desc;
+
+ int_desc = vm_locked.vm->interrupt_desc[i];
+ if (!int_desc.valid) {
+ break;
+ }
+ plat_interrupts_disable(int_desc.interrupt_id, core_pos);
+ }
+}
+
static struct vcpu *plat_ffa_find_target_vcpu(struct vcpu *current,
uint32_t interrupt_id)
{
@@ -2709,9 +2728,11 @@
uint32_t error_code)
{
struct vcpu_locked current_locked;
+ struct vm_locked vm_locked;
enum partition_runtime_model rt_model;
struct ffa_value ret = (struct ffa_value){.func = FFA_INTERRUPT_32};
+ vm_locked = vm_lock(current->vm);
current_locked = vcpu_lock(current);
rt_model = current_locked.vcpu->rt_model;
@@ -2722,6 +2743,8 @@
atomic_store_explicit(¤t->vm->aborting, true,
memory_order_relaxed);
+ plat_ffa_free_vm_resources(vm_locked);
+
if (sp_boot_next(current_locked, next)) {
goto out;
}
@@ -2741,6 +2764,7 @@
ret = ffa_error(FFA_NOT_SUPPORTED);
out:
vcpu_unlock(¤t_locked);
+ vm_unlock(&vm_locked);
return ret;
}
@@ -2855,3 +2879,14 @@
return ret;
}
+
+/**
+ * Reclaim all resources belonging to VM in aborted state.
+ */
+void plat_ffa_free_vm_resources(struct vm_locked vm_locked)
+{
+ /*
+ * Gracefully disable all interrupts belonging to SP.
+ */
+ plat_ffa_disable_vm_interrupts(vm_locked);
+}
diff --git a/src/arch/fake/hypervisor/ffa.c b/src/arch/fake/hypervisor/ffa.c
index 4e2fedd..a7a30b6 100644
--- a/src/arch/fake/hypervisor/ffa.c
+++ b/src/arch/fake/hypervisor/ffa.c
@@ -668,3 +668,8 @@
{
return false;
}
+
+void plat_ffa_free_vm_resources(struct vm_locked vm_locked)
+{
+ (void)vm_locked;
+}