feat(indirect message): add FFA_RXTX_UNMAP forwarding to SPMC

FFA_RXTX_UNMAP has to be forwarded to SPMC to allow it to unmap VM's
buffers, mapped through FFA_RXTX_MAP forwarding.

Change-Id: Ieb8dc04cc61b197023da0f5aa3612cf5a649d9c8
Signed-off-by: Federico Recanati <federico.recanati@arm.com>
diff --git a/src/arch/aarch64/plat/ffa/absent.c b/src/arch/aarch64/plat/ffa/absent.c
index c8e7d60..1a759f1 100644
--- a/src/arch/aarch64/plat/ffa/absent.c
+++ b/src/arch/aarch64/plat/ffa/absent.c
@@ -104,6 +104,11 @@
 	(void)vm_locked;
 }
 
+void plat_ffa_rxtx_unmap_forward(ffa_vm_id_t id)
+{
+	(void)id;
+}
+
 bool plat_ffa_direct_request_forward(ffa_vm_id_t receiver_vm_id,
 				     struct ffa_value args,
 				     struct ffa_value *ret)
diff --git a/src/arch/aarch64/plat/ffa/hypervisor.c b/src/arch/aarch64/plat/ffa/hypervisor.c
index c64e0c6..6dcb117 100644
--- a/src/arch/aarch64/plat/ffa/hypervisor.c
+++ b/src/arch/aarch64/plat/ffa/hypervisor.c
@@ -562,6 +562,30 @@
 	plat_ffa_rxtx_map_spmc(pa_init(0), pa_init(0), 0);
 }
 
+void plat_ffa_rxtx_unmap_forward(ffa_vm_id_t id)
+{
+	struct ffa_value ret;
+	uint64_t func;
+
+	if (!ffa_tee_enabled) {
+		return;
+	}
+
+	/* Hypervisor always forwards forward RXTX_UNMAP to SPMC. */
+	ret = arch_other_world_call((struct ffa_value){
+		.func = FFA_RXTX_UNMAP_32, .arg1 = id << 16});
+	func = ret.func & ~SMCCC_CONVENTION_MASK;
+	if (ret.func == SMCCC_ERROR_UNKNOWN) {
+		panic("Unknown error forwarding RXTX_UNMAP.\n");
+	} else if (func == FFA_ERROR_32) {
+		panic("Error %d forwarding RX/TX buffers.\n", ret.arg2);
+	} else if (func != FFA_SUCCESS_32) {
+		panic("Unexpected function %#x returned forwarding RX/TX "
+		      "buffers.",
+		      ret.func);
+	}
+}
+
 bool plat_ffa_is_mem_perm_get_valid(const struct vcpu *current)
 {
 	(void)current;
diff --git a/src/arch/aarch64/plat/ffa/spmc.c b/src/arch/aarch64/plat/ffa/spmc.c
index 2ba25d4..7cfbbd9 100644
--- a/src/arch/aarch64/plat/ffa/spmc.c
+++ b/src/arch/aarch64/plat/ffa/spmc.c
@@ -415,6 +415,11 @@
 	(void)vm_locked;
 }
 
+void plat_ffa_rxtx_unmap_forward(ffa_vm_id_t id)
+{
+	(void)id;
+}
+
 bool plat_ffa_is_notification_get_valid(struct vcpu *current,
 					ffa_vm_id_t receiver_id, uint32_t flags)
 {
diff --git a/src/arch/fake/hypervisor/ffa.c b/src/arch/fake/hypervisor/ffa.c
index ab84b72..830544a 100644
--- a/src/arch/fake/hypervisor/ffa.c
+++ b/src/arch/fake/hypervisor/ffa.c
@@ -79,6 +79,11 @@
 	return false;
 }
 
+void plat_ffa_rxtx_unmap_forward(ffa_vm_id_t id)
+{
+	(void)id;
+}
+
 bool plat_ffa_direct_request_forward(ffa_vm_id_t receiver_vm_id,
 				     struct ffa_value args,
 				     struct ffa_value *ret)