feat: initial support for FFA_ABORT ABI to abort partition

This patch adds initial support for the newly introduced FFA_ABORT ABI.
It is invoked by partition, to enter aborted state, when it encounters
a fatal error.

Subsequent patches will add incremental support for handling this ABI by
partition manager.

Change-Id: I601a0bf4efd61f5008285b6712107795c65c0332
Signed-off-by: Madhukar Pappireddy <madhukar.pappireddy@arm.com>
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index 56ca9e0..c0989cf 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -585,7 +585,10 @@
 	case FFA_ERROR_32:
 		*args = ffa_cpu_cycles_error_32(current, next, args->arg2);
 		return true;
-
+	case FFA_ABORT_32:
+	case FFA_ABORT_64:
+		*args = api_ffa_abort(current, next, args);
+		return true;
 	default:
 		return false;
 	}
@@ -1110,6 +1113,48 @@
 	return r;
 }
 
+/**
+ * Aborts execution of a partition when a fatal error occurs on a vCPU and
+ * triggers the SPMC to reclaim all resources allocated to it.
+ */
+struct ffa_value ffa_partition_abort(struct vcpu *current, struct vcpu **next)
+{
+	struct vm_locked vm_locked;
+	struct ffa_value ret;
+	struct vcpu_locked current_locked;
+
+	dlog_notice("Aborting VM %#x vCPU %u\n", current->vm->id,
+		    vcpu_index(current));
+
+	vm_locked = vm_lock(current->vm);
+
+	atomic_store_explicit(&current->vm->aborting, true,
+			      memory_order_relaxed);
+	current_locked = vcpu_lock(current);
+
+	/*
+	 * A partition exection is in ABORTED state after it encounters a fatal
+	 * error.
+	 */
+	current->state = VCPU_STATE_ABORTED;
+
+	/*
+	 * SPMC de-allocates and/or uninitializes all the resources allocated
+	 * to the partition.
+	 */
+	ffa_vm_free_resources(vm_locked);
+	vm_unlock(&vm_locked);
+
+	/*
+	 * SPMC performs necessary operations based on the abort action for
+	 * SP.
+	 */
+	ret = ffa_cpu_cycles_abort(current_locked, next);
+	vcpu_unlock(&current_locked);
+
+	return ret;
+}
+
 struct vcpu *sync_lower_exception(uintreg_t esr, uintreg_t far)
 {
 	struct vcpu *vcpu = current();