fix: check support of direct requests messaging

The FF-A partitions have the supported messaging method configured in
their respective manifest.
This patch adds a check to the sender and receiver support of the
messaging method in the handler of FFA_MSG_SEND_DIRECT_REQ.

Change-Id: Ib3f844caef158ece2ac78fbd477e245f4d690b9c
Signed-off-by: J-Alves <joao.alves@arm.com>
diff --git a/src/api.c b/src/api.c
index 8ce4136..911b1ad 100644
--- a/src/api.c
+++ b/src/api.c
@@ -2074,6 +2074,14 @@
 	}
 
 	/*
+	 * Check if sender supports sending direct message req, and if
+	 * receiver supports receipt of direct message requests.
+	 */
+	if (!plat_ffa_is_direct_request_supported(current->vm, receiver_vm)) {
+		return ffa_error(FFA_DENIED);
+	}
+
+	/*
 	 * Per PSA FF-A EAC spec section 4.4.1 the firmware framework supports
 	 * UP (migratable) or MP partitions with a number of vCPUs matching the
 	 * number of PEs in the system. It further states that MP partitions
diff --git a/src/arch/aarch64/hypervisor/other_world.c b/src/arch/aarch64/hypervisor/other_world.c
index 775f33c..652b645 100644
--- a/src/arch/aarch64/hypervisor/other_world.c
+++ b/src/arch/aarch64/hypervisor/other_world.c
@@ -35,6 +35,10 @@
 		goto out;
 	}
 
+	/* Enabling all communication methods for the other world. */
+	other_world_vm->messaging_method =
+		FFA_PARTITION_DIRECT_REQ_RECV | FFA_PARTITION_DIRECT_REQ_SEND;
+
 	ret = true;
 
 out:
diff --git a/src/arch/aarch64/plat/ffa/absent.c b/src/arch/aarch64/plat/ffa/absent.c
index 15fd844..c6a7d4c 100644
--- a/src/arch/aarch64/plat/ffa/absent.c
+++ b/src/arch/aarch64/plat/ffa/absent.c
@@ -55,6 +55,15 @@
 	return false;
 }
 
+bool plat_ffa_is_direct_request_supported(struct vm *sender_vm,
+					  struct vm *receiver_vm)
+{
+	(void)sender_vm;
+	(void)receiver_vm;
+
+	return false;
+}
+
 /**
  * Check validity of a FF-A direct message response.
  */
diff --git a/src/arch/aarch64/plat/ffa/hypervisor.c b/src/arch/aarch64/plat/ffa/hypervisor.c
index d1f4607..b7361fb 100644
--- a/src/arch/aarch64/plat/ffa/hypervisor.c
+++ b/src/arch/aarch64/plat/ffa/hypervisor.c
@@ -174,6 +174,19 @@
 	return false;
 }
 
+bool plat_ffa_is_direct_request_supported(struct vm *sender_vm,
+					  struct vm *receiver_vm)
+{
+	(void)sender_vm;
+	(void)receiver_vm;
+
+	/*
+	 * As Hypervisor is only meant to be used as a test artifact, allow
+	 * direct messaging for all VMs.
+	 */
+	return true;
+}
+
 /**
  * Check validity of a FF-A direct message response.
  */
diff --git a/src/arch/aarch64/plat/ffa/spmc.c b/src/arch/aarch64/plat/ffa/spmc.c
index 4e0074a..b24ed8a 100644
--- a/src/arch/aarch64/plat/ffa/spmc.c
+++ b/src/arch/aarch64/plat/ffa/spmc.c
@@ -189,6 +189,30 @@
 }
 
 /**
+ * Check that the receiver supports receipt of direct requests, and that the
+ * sender supports sending direct messaging requests, in accordance to their
+ * respective configurations at the partition's FF-A manifest.
+ */
+bool plat_ffa_is_direct_request_supported(struct vm *sender_vm,
+					  struct vm *receiver_vm)
+{
+	if (!vm_supports_messaging_method(sender_vm,
+					  FFA_PARTITION_DIRECT_REQ_SEND)) {
+		dlog_verbose("Sender can't send direct message requests.\n");
+		return false;
+	}
+
+	if (!vm_supports_messaging_method(receiver_vm,
+					  FFA_PARTITION_DIRECT_REQ_RECV)) {
+		dlog_verbose(
+			"Receiver can't receive direct message requests.\n");
+		return false;
+	}
+
+	return true;
+}
+
+/**
  * Check validity of a FF-A direct message response.
  */
 bool plat_ffa_is_direct_response_valid(struct vcpu *current,
diff --git a/src/arch/fake/hypervisor/ffa.c b/src/arch/fake/hypervisor/ffa.c
index d043c6e..91bebd4 100644
--- a/src/arch/fake/hypervisor/ffa.c
+++ b/src/arch/fake/hypervisor/ffa.c
@@ -40,6 +40,15 @@
 	return true;
 }
 
+bool plat_ffa_is_direct_request_supported(struct vm *sender_vm,
+					  struct vm *receiver_vm)
+{
+	(void)sender_vm;
+	(void)receiver_vm;
+
+	return false;
+}
+
 bool plat_ffa_is_direct_response_valid(struct vcpu *current,
 				       ffa_vm_id_t sender_vm_id,
 				       ffa_vm_id_t receiver_vm_id)
diff --git a/src/vm.c b/src/vm.c
index 43a52f2..159c08f 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -899,3 +899,11 @@
 	 */
 	return current_state == FULL;
 }
+
+/**
+ * Checks VM's messaging method support.
+ */
+bool vm_supports_messaging_method(struct vm *vm, uint8_t msg_method)
+{
+	return (vm->messaging_method & msg_method) != 0;
+}