FF-A: Direct Messaging from VMs to SPs
Hypervisor forward direct request from a VM, to the SWd if receiver is
an SP.
Change-Id: Id2a2142ddc8c13c8e371347308c78c8a1ebc0b4a
Signed-off-by: J-Alves <joao.alves@arm.com>
diff --git a/src/api.c b/src/api.c
index 70df9f7..9510042 100644
--- a/src/api.c
+++ b/src/api.c
@@ -1757,7 +1757,7 @@
struct vcpu *current,
struct vcpu **next)
{
- struct ffa_value ret = (struct ffa_value){.func = FFA_INTERRUPT_32};
+ struct ffa_value ret;
struct vm *receiver_vm;
struct vcpu *receiver_vcpu;
struct two_vcpu_locked vcpus_locked;
@@ -1771,6 +1771,13 @@
return ffa_error(FFA_INVALID_PARAMETERS);
}
+ if (arch_other_world_direct_request_forward(receiver_vm_id, args,
+ &ret)) {
+ return ret;
+ }
+
+ ret = (struct ffa_value){.func = FFA_INTERRUPT_32};
+
receiver_vm = vm_find(receiver_vm_id);
if (receiver_vm == NULL) {
return ffa_error(FFA_INVALID_PARAMETERS);
diff --git a/src/arch/aarch64/hypervisor/other_world.c b/src/arch/aarch64/hypervisor/other_world.c
index a3fa12b..2e1aebc 100644
--- a/src/arch/aarch64/hypervisor/other_world.c
+++ b/src/arch/aarch64/hypervisor/other_world.c
@@ -193,6 +193,31 @@
return false;
}
+bool arch_other_world_direct_request_forward(ffa_vm_id_t receiver_vm_id,
+ struct ffa_value args,
+ struct ffa_value *ret)
+{
+#if SECURE_WORLD == 1
+ /*
+ * SPs are not supposed to issue requests to VMs.
+ */
+ (void)receiver_vm_id;
+ (void)args;
+ (void)ret;
+
+#else
+ /*
+ * VM's requests should be forwarded to the SPMC, if receiver is an SP.
+ */
+ if (!vm_id_is_current_world(receiver_vm_id)) {
+ *ret = arch_other_world_call(args);
+ return true;
+ }
+#endif
+
+ return false;
+}
+
struct ffa_value arch_other_world_call(struct ffa_value args)
{
return smc_ffa_call(args);
diff --git a/src/arch/fake/hypervisor/other_world.c b/src/arch/fake/hypervisor/other_world.c
index ebddb41..ddba66a 100644
--- a/src/arch/fake/hypervisor/other_world.c
+++ b/src/arch/fake/hypervisor/other_world.c
@@ -44,3 +44,13 @@
return true;
}
+
+bool arch_other_world_direct_request_forward(ffa_vm_id_t receiver_vm_id,
+ struct ffa_value args,
+ struct ffa_value *ret)
+{
+ (void)receiver_vm_id;
+ (void)args;
+ (void)ret;
+ return false;
+}