Tell TF-A in EL3 about TEE message buffers.
This must be enabled by a flag in the manifest, as it won't work without
the matching support in TF-A, e.g. in the case of running tests on QEMU
without TF-A.
Bug: 132429380
Change-Id: I0a0848c7b1afb416d98c0afeabcc4601abf9d193
diff --git a/src/BUILD.gn b/src/BUILD.gn
index 3220b4e..c9ecd1a 100644
--- a/src/BUILD.gn
+++ b/src/BUILD.gn
@@ -40,6 +40,7 @@
deps = [
":src_testable",
"//project/${project}/${plat_name}",
+ "//src/arch/${plat_arch}/hypervisor:tee",
plat_boot_flow,
plat_console,
plat_iommu,
@@ -58,7 +59,6 @@
"panic.c",
"spci_memory.c",
"vcpu.c",
- "vm.c",
]
deps = [
@@ -69,8 +69,9 @@
":memiter",
":mm",
":std",
- ":string",
+ ":vm",
"//src/arch/${plat_arch}/hypervisor",
+ "//src/arch/${plat_arch}/hypervisor:tee",
"//vmlib",
plat_boot_flow,
plat_console,
@@ -91,6 +92,12 @@
]
}
+source_set("vm") {
+ sources = [
+ "vm.c",
+ ]
+}
+
# Standard library functions.
source_set("std") {
sources = [
diff --git a/src/arch/aarch64/hypervisor/BUILD.gn b/src/arch/aarch64/hypervisor/BUILD.gn
index d5db714..67e68bd 100644
--- a/src/arch/aarch64/hypervisor/BUILD.gn
+++ b/src/arch/aarch64/hypervisor/BUILD.gn
@@ -22,6 +22,16 @@
path = "hf/arch/offsets.h"
}
+source_set("tee") {
+ public_configs = [ "//src/arch/aarch64:config" ]
+ sources = [
+ "tee.c",
+ ]
+ deps = [
+ "//src:vm",
+ ]
+}
+
# Hypervisor specific code.
source_set("hypervisor") {
public_configs = [ "//src/arch/aarch64:config" ]
@@ -38,7 +48,6 @@
"handler.c",
"perfmon.c",
"psci_handler.c",
- "tee.c",
"vm.c",
]
diff --git a/src/arch/aarch64/hypervisor/tee.c b/src/arch/aarch64/hypervisor/tee.c
index de6b094..c3885ac 100644
--- a/src/arch/aarch64/hypervisor/tee.c
+++ b/src/arch/aarch64/hypervisor/tee.c
@@ -16,10 +16,49 @@
#include "hf/arch/tee.h"
+#include "hf/check.h"
+#include "hf/dlog.h"
+#include "hf/panic.h"
#include "hf/spci.h"
+#include "hf/vm.h"
#include "smc.h"
+void arch_tee_init(void)
+{
+ struct vm *tee_vm = vm_find(HF_TEE_VM_ID);
+ struct spci_value ret;
+ uint32_t func;
+
+ CHECK(tee_vm != NULL);
+ /*
+ * Note that send and recv are swapped around, as the send buffer from
+ * Hafnium's perspective is the recv buffer from the EL3 dispatcher's
+ * perspective and vice-versa.
+ */
+ dlog_verbose("Setting up buffers for TEE.\n");
+ ret = arch_tee_call((struct spci_value){
+ .func = SPCI_RXTX_MAP_64,
+ .arg1 = pa_addr(pa_from_va(va_from_ptr(tee_vm->mailbox.recv))),
+ .arg2 = pa_addr(pa_from_va(va_from_ptr(tee_vm->mailbox.send))),
+ .arg3 = HF_MAILBOX_SIZE / SPCI_PAGE_SIZE});
+ func = ret.func & ~SMCCC_CONVENTION_MASK;
+ if (ret.func == SMCCC_ERROR_UNKNOWN) {
+ dlog_error(
+ "Unknown function setting up TEE message buffers. "
+ "Memory sharing with TEE will not work.\n");
+ return;
+ }
+ if (func == SPCI_ERROR_32) {
+ panic("Error %d setting up TEE message buffers.", ret.arg2);
+ } else if (func != SPCI_SUCCESS_32) {
+ panic("Unexpected function %#x returned setting up TEE message "
+ "buffers.",
+ ret.func);
+ }
+ dlog_verbose("TEE finished setting up buffers.\n");
+}
+
struct spci_value arch_tee_call(struct spci_value args)
{
return smc_forward(args.func, args.arg1, args.arg2, args.arg3,
diff --git a/src/arch/fake/hypervisor/BUILD.gn b/src/arch/fake/hypervisor/BUILD.gn
index e7e970f..1afcca6 100644
--- a/src/arch/fake/hypervisor/BUILD.gn
+++ b/src/arch/fake/hypervisor/BUILD.gn
@@ -15,9 +15,14 @@
source_set("hypervisor") {
sources = [
"cpu.c",
- "tee.c",
]
deps = [
"//src/arch/fake",
]
}
+
+source_set("tee") {
+ sources = [
+ "tee.c",
+ ]
+}
diff --git a/src/init.c b/src/init.c
index 2f241b8..d224d49 100644
--- a/src/init.c
+++ b/src/init.c
@@ -19,6 +19,8 @@
#include <stdalign.h>
#include <stddef.h>
+#include "hf/arch/tee.h"
+
#include "hf/api.h"
#include "hf/boot_flow.h"
#include "hf/boot_params.h"
@@ -158,5 +160,10 @@
/* Enable TLB invalidation for VM page table updates. */
mm_vm_enable_invalidation();
+ if (manifest.spci_tee_enabled) {
+ /* Set up message buffers for TEE dispatcher. */
+ arch_tee_init();
+ }
+
dlog_info("Hafnium initialisation completed\n");
}
diff --git a/src/manifest.c b/src/manifest.c
index 438b5d0..9b80106 100644
--- a/src/manifest.c
+++ b/src/manifest.c
@@ -280,6 +280,8 @@
return MANIFEST_ERROR_NOT_COMPATIBLE;
}
+ TRY(read_bool(&hyp_node, "spci_tee", &manifest->spci_tee_enabled));
+
/* Iterate over reserved VM IDs and check no such nodes exist. */
for (i = 0; i < HF_VM_ID_OFFSET; i++) {
spci_vm_id_t vm_id = (spci_vm_id_t)i;