refactor(plat/ffa): extract direct messaging
Extract the direct messaging interface from `plat/ffa.h` to
`plat/ffa/direct_messaging.h`.
Change-Id: Idab65bcea7b3e9975a293fa4d83b2b9a6c90b5e8
Signed-off-by: Karl Meakin <karl.meakin@arm.com>
diff --git a/inc/hf/arch/plat/ffa.h b/inc/hf/arch/plat/ffa.h
index d5367fd..7cca81c 100644
--- a/inc/hf/arch/plat/ffa.h
+++ b/inc/hf/arch/plat/ffa.h
@@ -10,7 +10,6 @@
#include "hf/addr.h"
#include "hf/ffa.h"
-#include "hf/ffa_memory_internal.h"
#include "hf/manifest.h"
#include "hf/vcpu.h"
#include "hf/vm.h"
@@ -24,19 +23,6 @@
bool plat_ffa_is_memory_send_valid(ffa_id_t receiver, ffa_id_t sender,
uint32_t share_func, bool multiple_borrower);
-bool plat_ffa_is_direct_request_valid(struct vcpu *current,
- ffa_id_t sender_vm_id,
- ffa_id_t receiver_vm_id);
-bool plat_ffa_is_direct_response_valid(struct vcpu *current,
- ffa_id_t sender_vm_id,
- ffa_id_t receiver_vm_id);
-bool plat_ffa_is_direct_request_supported(struct vm *sender_vm,
- struct vm *receiver_vm,
- uint32_t func);
-bool plat_ffa_direct_request_forward(ffa_id_t receiver_vm_id,
- struct ffa_value args,
- struct ffa_value *ret);
-
bool plat_ffa_rx_release_forward(struct vm_locked vm_locked,
struct ffa_value *ret);
@@ -255,13 +241,6 @@
void plat_ffa_init_schedule_mode_ffa_run(struct vcpu_locked current_locked,
struct vcpu_locked target_locked);
-void plat_ffa_wind_call_chain_ffa_direct_req(
- struct vcpu_locked current_locked,
- struct vcpu_locked receiver_vcpu_locked, ffa_id_t sender_vm_id);
-
-void plat_ffa_unwind_call_chain_ffa_direct_resp(
- struct vcpu_locked current_locked, struct vcpu_locked next_locked);
-
void plat_ffa_enable_virtual_interrupts(struct vcpu_locked current_locked,
struct vm_locked vm_locked);
diff --git a/inc/hf/arch/plat/ffa/direct_messaging.h b/inc/hf/arch/plat/ffa/direct_messaging.h
new file mode 100644
index 0000000..d19e758
--- /dev/null
+++ b/inc/hf/arch/plat/ffa/direct_messaging.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2024 The Hafnium Authors.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/BSD-3-Clause.
+ */
+
+#pragma once
+
+#include "hf/vcpu.h"
+#include "hf/vm.h"
+
+/** Check validity of a FF-A direct message request. */
+bool plat_ffa_is_direct_request_valid(struct vcpu *current,
+ ffa_id_t sender_vm_id,
+ ffa_id_t receiver_vm_id);
+
+/** Check validity of a FF-A direct message response. */
+bool plat_ffa_is_direct_response_valid(struct vcpu *current,
+ ffa_id_t sender_vm_id,
+ ffa_id_t receiver_vm_id);
+
+bool plat_ffa_is_direct_request_supported(struct vm *sender_vm,
+ struct vm *receiver_vm,
+ uint32_t func);
+
+bool plat_ffa_direct_request_forward(ffa_id_t receiver_vm_id,
+ struct ffa_value args,
+ struct ffa_value *ret);
+
+void plat_ffa_wind_call_chain_ffa_direct_req(
+ struct vcpu_locked current_locked,
+ struct vcpu_locked receiver_vcpu_locked, ffa_id_t sender_vm_id);
+
+void plat_ffa_unwind_call_chain_ffa_direct_resp(
+ struct vcpu_locked current_locked, struct vcpu_locked next_locked);
diff --git a/src/api.c b/src/api.c
index 957cabe..bc7ad48 100644
--- a/src/api.c
+++ b/src/api.c
@@ -14,6 +14,7 @@
#include "hf/arch/mm.h"
#include "hf/arch/other_world.h"
#include "hf/arch/plat/ffa.h"
+#include "hf/arch/plat/ffa/direct_messaging.h"
#include "hf/arch/timer.h"
#include "hf/arch/vm.h"
diff --git a/src/arch/aarch64/plat/ffa/BUILD.gn b/src/arch/aarch64/plat/ffa/BUILD.gn
index 5b57f52..a90bc9e 100644
--- a/src/arch/aarch64/plat/ffa/BUILD.gn
+++ b/src/arch/aarch64/plat/ffa/BUILD.gn
@@ -22,7 +22,10 @@
":hypervisor_config",
]
deps = [ "//vmlib/${plat_arch}:smc_call" ]
- sources = [ "hypervisor.c" ]
+ sources = [
+ "hypervisor.c",
+ "hypervisor/direct_messaging.c",
+ ]
}
source_set("spmc") {
@@ -36,5 +39,6 @@
sources = [
"//src/arch/aarch64/hypervisor/simd.c",
"spmc.c",
+ "spmc/direct_messaging.c",
]
}
diff --git a/src/arch/aarch64/plat/ffa/hypervisor.c b/src/arch/aarch64/plat/ffa/hypervisor.c
index 2d23e7d..beeb9e7 100644
--- a/src/arch/aarch64/plat/ffa/hypervisor.c
+++ b/src/arch/aarch64/plat/ffa/hypervisor.c
@@ -6,7 +6,6 @@
* https://opensource.org/licenses/BSD-3-Clause.
*/
-#include "hf/arch/barriers.h"
#include "hf/arch/ffa.h"
#include "hf/arch/other_world.h"
#include "hf/arch/plat/ffa.h"
@@ -15,14 +14,11 @@
#include "hf/dlog.h"
#include "hf/ffa.h"
#include "hf/ffa_internal.h"
-#include "hf/ffa_memory.h"
#include "hf/ffa_memory_internal.h"
-#include "hf/std.h"
#include "hf/vcpu.h"
#include "hf/vm.h"
#include "hf/vm_ids.h"
-#include "msr.h"
#include "smc.h"
#include "sysregs.h"
@@ -198,24 +194,6 @@
}
/**
- * Check validity of a FF-A direct message request.
- */
-bool plat_ffa_is_direct_request_valid(struct vcpu *current,
- ffa_id_t sender_vm_id,
- ffa_id_t receiver_vm_id)
-{
- ffa_id_t current_vm_id = current->vm->id;
-
- /*
- * The primary VM can send direct message request to
- * any other VM (but itself) or SP, but can't spoof
- * a different sender.
- */
- return sender_vm_id != receiver_vm_id &&
- sender_vm_id == current_vm_id && vm_is_primary(current->vm);
-}
-
-/**
* Check validity of the calls:
* FFA_NOTIFICATION_BITMAP_CREATE/FFA_NOTIFICATION_BITMAP_DESTROY.
*/
@@ -232,74 +210,6 @@
return ffa_error(FFA_NOT_SUPPORTED);
}
-bool plat_ffa_is_direct_request_supported(struct vm *sender_vm,
- struct vm *receiver_vm, uint32_t func)
-{
- (void)sender_vm;
- (void)receiver_vm;
- (void)func;
-
- /*
- * 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.
- */
-bool plat_ffa_is_direct_response_valid(struct vcpu *current,
- ffa_id_t sender_vm_id,
- ffa_id_t receiver_vm_id)
-{
- ffa_id_t current_vm_id = current->vm->id;
-
- /*
- * Secondary VMs can send direct message responses to
- * the PVM, but can't spoof a different sender.
- */
- return sender_vm_id != receiver_vm_id &&
- sender_vm_id == current_vm_id &&
- receiver_vm_id == HF_PRIMARY_VM_ID;
-}
-
-bool plat_ffa_direct_request_forward(ffa_id_t receiver_vm_id,
- struct ffa_value args,
- struct ffa_value *ret)
-{
- if (!ffa_tee_enabled) {
- dlog_verbose("Not forwarding: ffa_tee_enabled is false\n");
- return false;
- }
-
- /*
- * VM's requests should be forwarded to the SPMC, if receiver is an SP.
- */
- if (vm_id_is_current_world(receiver_vm_id)) {
- dlog_verbose(
- "Not forwarding: receiver VM %#x is in the same "
- "world\n",
- receiver_vm_id);
- return false;
- }
-
- switch (args.func) {
- case FFA_MSG_SEND_DIRECT_REQ_32:
- case FFA_MSG_SEND_DIRECT_REQ_64:
- *ret = arch_other_world_call(args);
- break;
- case FFA_MSG_SEND_DIRECT_REQ2_64:
- *ret = arch_other_world_call_ext(args);
- break;
- default:
- panic("Invalid direct message function %#x\n", args.func);
- break;
- }
-
- return true;
-}
-
bool plat_ffa_rx_release_forward(struct vm_locked vm_locked,
struct ffa_value *ret)
{
@@ -1174,30 +1084,12 @@
(void)target_locked;
}
-void plat_ffa_wind_call_chain_ffa_direct_req(
- struct vcpu_locked current_locked,
- struct vcpu_locked receiver_vcpu_locked, ffa_id_t sender_vm_id)
-{
- /* Calls chains not supported in the Hypervisor/VMs. */
- (void)current_locked;
- (void)receiver_vcpu_locked;
- (void)sender_vm_id;
-}
-
bool plat_ffa_is_spmd_lp_id(ffa_id_t vm_id)
{
(void)vm_id;
return false;
}
-void plat_ffa_unwind_call_chain_ffa_direct_resp(
- struct vcpu_locked current_locked, struct vcpu_locked next_locked)
-{
- /* Calls chains not supported in the Hypervisor/VMs. */
- (void)current_locked;
- (void)next_locked;
-}
-
/**
* Enable relevant virtual interrupts for VMs.
*/
diff --git a/src/arch/aarch64/plat/ffa/hypervisor/direct_messaging.c b/src/arch/aarch64/plat/ffa/hypervisor/direct_messaging.c
new file mode 100644
index 0000000..e9c0562
--- /dev/null
+++ b/src/arch/aarch64/plat/ffa/hypervisor/direct_messaging.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2024 The Hafnium Authors.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/BSD-3-Clause.
+ */
+
+#include "hf/arch/plat/ffa/direct_messaging.h"
+
+#include "hf/arch/other_world.h"
+
+#include "hf/vcpu.h"
+#include "hf/vm.h"
+
+#include "hypervisor.h"
+
+/**
+ * Check validity of a FF-A direct message request.
+ */
+bool plat_ffa_is_direct_request_valid(struct vcpu *current,
+ ffa_id_t sender_vm_id,
+ ffa_id_t receiver_vm_id)
+{
+ ffa_id_t current_vm_id = current->vm->id;
+
+ /*
+ * The primary VM can send direct message request to
+ * any other VM (but itself) or SP, but can't spoof
+ * a different sender.
+ */
+ return sender_vm_id != receiver_vm_id &&
+ sender_vm_id == current_vm_id && vm_is_primary(current->vm);
+}
+
+bool plat_ffa_is_direct_request_supported(struct vm *sender_vm,
+ struct vm *receiver_vm, uint32_t func)
+{
+ (void)sender_vm;
+ (void)receiver_vm;
+ (void)func;
+
+ /*
+ * 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.
+ */
+bool plat_ffa_is_direct_response_valid(struct vcpu *current,
+ ffa_id_t sender_vm_id,
+ ffa_id_t receiver_vm_id)
+{
+ ffa_id_t current_vm_id = current->vm->id;
+
+ /*
+ * Secondary VMs can send direct message responses to
+ * the PVM, but can't spoof a different sender.
+ */
+ return sender_vm_id != receiver_vm_id &&
+ sender_vm_id == current_vm_id &&
+ receiver_vm_id == HF_PRIMARY_VM_ID;
+}
+
+bool plat_ffa_direct_request_forward(ffa_id_t receiver_vm_id,
+ struct ffa_value args,
+ struct ffa_value *ret)
+{
+ if (!plat_ffa_is_tee_enabled()) {
+ dlog_verbose("Not forwarding: ffa_tee_enabled is false\n");
+ return false;
+ }
+
+ /*
+ * VM's requests should be forwarded to the SPMC, if receiver is an SP.
+ */
+ if (vm_id_is_current_world(receiver_vm_id)) {
+ dlog_verbose(
+ "Not forwarding: receiver VM %#x is in the same "
+ "world\n",
+ receiver_vm_id);
+ return false;
+ }
+
+ switch (args.func) {
+ case FFA_MSG_SEND_DIRECT_REQ_32:
+ case FFA_MSG_SEND_DIRECT_REQ_64:
+ *ret = arch_other_world_call(args);
+ break;
+ case FFA_MSG_SEND_DIRECT_REQ2_64:
+ *ret = arch_other_world_call_ext(args);
+ break;
+ default:
+ panic("Invalid direct message function %#x\n", args.func);
+ break;
+ }
+
+ return true;
+}
+
+void plat_ffa_wind_call_chain_ffa_direct_req(
+ struct vcpu_locked current_locked,
+ struct vcpu_locked receiver_vcpu_locked, ffa_id_t sender_vm_id)
+{
+ /* Calls chains not supported in the Hypervisor/VMs. */
+ (void)current_locked;
+ (void)receiver_vcpu_locked;
+ (void)sender_vm_id;
+}
+
+void plat_ffa_unwind_call_chain_ffa_direct_resp(
+ struct vcpu_locked current_locked, struct vcpu_locked next_locked)
+{
+ /* Calls chains not supported in the Hypervisor/VMs. */
+ (void)current_locked;
+ (void)next_locked;
+}
diff --git a/src/arch/aarch64/plat/ffa/spmc.c b/src/arch/aarch64/plat/ffa/spmc.c
index 41abf27..f381332 100644
--- a/src/arch/aarch64/plat/ffa/spmc.c
+++ b/src/arch/aarch64/plat/ffa/spmc.c
@@ -10,8 +10,8 @@
#include "hf/arch/gicv3.h"
#include "hf/arch/host_timer.h"
#include "hf/arch/mmu.h"
-#include "hf/arch/other_world.h"
#include "hf/arch/plat/ffa.h"
+#include "hf/arch/std.h"
#include "hf/arch/sve.h"
#include "hf/arch/vmid_base.h"
@@ -25,15 +25,12 @@
#include "hf/hf_ipi.h"
#include "hf/interrupt_desc.h"
#include "hf/plat/interrupts.h"
-#include "hf/std.h"
#include "hf/timer_mgmt.h"
#include "hf/vcpu.h"
#include "hf/vm.h"
-#include "vmapi/hf/call.h"
#include "vmapi/hf/ffa.h"
-#include "msr.h"
#include "smc.h"
#include "sysregs.h"
@@ -515,123 +512,6 @@
return (vm_id >= EL3_SPMD_LP_ID_START && vm_id <= EL3_SPMD_LP_ID_END);
}
-/**
- * Check validity of a FF-A direct message request.
- */
-bool plat_ffa_is_direct_request_valid(struct vcpu *current,
- ffa_id_t sender_vm_id,
- ffa_id_t receiver_vm_id)
-{
- ffa_id_t current_vm_id = current->vm->id;
-
- /*
- * The normal world can send direct message requests
- * via the Hypervisor to any SP. Currently SPs can only send
- * direct messages to each other and not to the NWd.
- * SPMD Logical partitions can also send direct messages.
- */
- return sender_vm_id != receiver_vm_id &&
- vm_id_is_current_world(receiver_vm_id) &&
- (sender_vm_id == current_vm_id ||
- (current_vm_id == HF_HYPERVISOR_VM_ID &&
- (plat_ffa_is_spmd_lp_id(sender_vm_id) ||
- !vm_id_is_current_world(sender_vm_id))));
-}
-
-/**
- * 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, uint32_t func)
-{
- uint16_t sender_method;
- uint16_t receiver_method;
- enum ffa_version sender_ffa_version = sender_vm->ffa_version;
- enum ffa_version receiver_ffa_version = receiver_vm->ffa_version;
-
- /* Check if version supports messaging function. */
- if (func == FFA_MSG_SEND_DIRECT_REQ2_64 &&
- sender_ffa_version < FFA_VERSION_1_2) {
- dlog_verbose(
- "Sender version does not allow usage of func id "
- "0x%x.\n",
- func);
- return false;
- }
-
- if (func == FFA_MSG_SEND_DIRECT_REQ2_64 &&
- receiver_ffa_version < FFA_VERSION_1_2) {
- dlog_verbose(
- "Receiver version does not allow usage of func id "
- "0x%x.\n",
- func);
- return false;
- }
-
- /*
- * Check if endpoint is configured to accept direct requests via given
- * method.
- */
- sender_method = (func == FFA_MSG_SEND_DIRECT_REQ2_64)
- ? FFA_PARTITION_DIRECT_REQ2_SEND
- : FFA_PARTITION_DIRECT_REQ_SEND;
- receiver_method = (func == FFA_MSG_SEND_DIRECT_REQ2_64)
- ? FFA_PARTITION_DIRECT_REQ2_RECV
- : FFA_PARTITION_DIRECT_REQ_RECV;
-
- if (!vm_supports_messaging_method(sender_vm, sender_method)) {
- dlog_verbose(
- "Sender can't send direct message requests via func id "
- "0x%x.\n",
- func);
- return false;
- }
-
- if (!vm_supports_messaging_method(receiver_vm, receiver_method)) {
- dlog_verbose(
- "Receiver can't receive direct message requests via "
- "func id 0x%x.\n",
- func);
- return false;
- }
-
- return true;
-}
-
-/**
- * Check validity of a FF-A direct message response.
- */
-bool plat_ffa_is_direct_response_valid(struct vcpu *current,
- ffa_id_t sender_vm_id,
- ffa_id_t receiver_vm_id)
-{
- ffa_id_t current_vm_id = current->vm->id;
-
- /*
- * Direct message responses emitted from a SP target either the NWd,
- * or EL3 SPMD logical partition or another SP.
- */
- return sender_vm_id != receiver_vm_id &&
- sender_vm_id == current_vm_id &&
- vm_id_is_current_world(sender_vm_id);
-}
-
-bool plat_ffa_direct_request_forward(ffa_id_t receiver_vm_id,
- struct ffa_value args,
- struct ffa_value *ret)
-{
- /*
- * SPs are not supposed to issue requests to VMs.
- */
- (void)receiver_vm_id;
- (void)args;
- (void)ret;
-
- return false;
-}
-
bool plat_ffa_rx_release_forward(struct vm_locked vm_locked,
struct ffa_value *ret)
{
diff --git a/src/arch/aarch64/plat/ffa/spmc/direct_messaging.c b/src/arch/aarch64/plat/ffa/spmc/direct_messaging.c
new file mode 100644
index 0000000..d0a74f9
--- /dev/null
+++ b/src/arch/aarch64/plat/ffa/spmc/direct_messaging.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2024 The Hafnium Authors.
+ *
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/BSD-3-Clause.
+ */
+
+#include "hf/arch/plat/ffa/direct_messaging.h"
+
+#include "hf/arch/plat/ffa.h"
+
+#include "hf/vm.h"
+
+bool plat_ffa_is_direct_request_valid(struct vcpu *current,
+ ffa_id_t sender_vm_id,
+ ffa_id_t receiver_vm_id)
+{
+ ffa_id_t current_vm_id = current->vm->id;
+
+ /*
+ * The normal world can send direct message requests
+ * via the Hypervisor to any SP. Currently SPs can only send
+ * direct messages to each other and not to the NWd.
+ * SPMD Logical partitions can also send direct messages.
+ */
+ return sender_vm_id != receiver_vm_id &&
+ vm_id_is_current_world(receiver_vm_id) &&
+ (sender_vm_id == current_vm_id ||
+ (current_vm_id == HF_HYPERVISOR_VM_ID &&
+ (plat_ffa_is_spmd_lp_id(sender_vm_id) ||
+ !vm_id_is_current_world(sender_vm_id))));
+}
+
+/**
+ * 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, uint32_t func)
+{
+ uint16_t sender_method;
+ uint16_t receiver_method;
+ enum ffa_version sender_ffa_version = sender_vm->ffa_version;
+ enum ffa_version receiver_ffa_version = receiver_vm->ffa_version;
+
+ /* Check if version supports messaging function. */
+ if (func == FFA_MSG_SEND_DIRECT_REQ2_64 &&
+ sender_ffa_version < FFA_VERSION_1_2) {
+ dlog_verbose(
+ "Sender version does not allow usage of func id "
+ "0x%x.\n",
+ func);
+ return false;
+ }
+
+ if (func == FFA_MSG_SEND_DIRECT_REQ2_64 &&
+ receiver_ffa_version < FFA_VERSION_1_2) {
+ dlog_verbose(
+ "Receiver version does not allow usage of func id "
+ "0x%x.\n",
+ func);
+ return false;
+ }
+
+ /*
+ * Check if endpoint is configured to accept direct requests via given
+ * method.
+ */
+ sender_method = (func == FFA_MSG_SEND_DIRECT_REQ2_64)
+ ? FFA_PARTITION_DIRECT_REQ2_SEND
+ : FFA_PARTITION_DIRECT_REQ_SEND;
+ receiver_method = (func == FFA_MSG_SEND_DIRECT_REQ2_64)
+ ? FFA_PARTITION_DIRECT_REQ2_RECV
+ : FFA_PARTITION_DIRECT_REQ_RECV;
+
+ if (!vm_supports_messaging_method(sender_vm, sender_method)) {
+ dlog_verbose(
+ "Sender can't send direct message requests via func id "
+ "0x%x.\n",
+ func);
+ return false;
+ }
+
+ if (!vm_supports_messaging_method(receiver_vm, receiver_method)) {
+ dlog_verbose(
+ "Receiver can't receive direct message requests via "
+ "func id 0x%x.\n",
+ func);
+ return false;
+ }
+
+ return true;
+}
+
+/** Check validity of a FF-A direct message response. */
+bool plat_ffa_is_direct_response_valid(struct vcpu *current,
+ ffa_id_t sender_vm_id,
+ ffa_id_t receiver_vm_id)
+{
+ ffa_id_t current_vm_id = current->vm->id;
+
+ /*
+ * Direct message responses emitted from a SP target either the NWd,
+ * or EL3 SPMD logical partition or another SP.
+ */
+ return sender_vm_id != receiver_vm_id &&
+ sender_vm_id == current_vm_id &&
+ vm_id_is_current_world(sender_vm_id);
+}
+
+bool plat_ffa_direct_request_forward(ffa_id_t receiver_vm_id,
+ struct ffa_value args,
+ struct ffa_value *ret)
+{
+ /*
+ * SPs are not supposed to issue requests to VMs.
+ */
+ (void)receiver_vm_id;
+ (void)args;
+ (void)ret;
+
+ return false;
+}
diff --git a/src/load.c b/src/load.c
index 9968eb7..fc9007f 100644
--- a/src/load.c
+++ b/src/load.c
@@ -13,6 +13,7 @@
#include "hf/arch/init.h"
#include "hf/arch/other_world.h"
#include "hf/arch/plat/ffa.h"
+#include "hf/arch/plat/ffa/direct_messaging.h"
#include "hf/arch/vm.h"
#include "hf/api.h"