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;
+}