feat(ff-a): save partitions version during ffa_version
This will be useful later when we may need to consider the version
of a partition when structuring a response to certain FF-A functions.
Also add a call to FFA_VERSION during initialization of the hypervisor
so the SPMC knows the hypervisors implemented version.
Signed-off-by: Daniel Boulby <daniel.boulby@arm.com>
Change-Id: Ia8f5f8a9589300311a1e129536acce0948d5a6bc
diff --git a/src/api.c b/src/api.c
index 56b8bc2..de2bf5b 100644
--- a/src/api.c
+++ b/src/api.c
@@ -1794,8 +1794,11 @@
}
/** Returns the version of the implemented FF-A specification. */
-struct ffa_value api_ffa_version(uint32_t requested_version)
+struct ffa_value api_ffa_version(struct vcpu *current,
+ uint32_t requested_version)
{
+ struct vm_locked current_vm_locked;
+
/*
* Ensure that both major and minor revision representation occupies at
* most 15 bits.
@@ -1809,6 +1812,10 @@
return (struct ffa_value){.func = (uint32_t)FFA_NOT_SUPPORTED};
}
+ current_vm_locked = vm_lock(current->vm);
+ current_vm_locked.vm->ffa_version = requested_version;
+ vm_unlock(¤t_vm_locked);
+
return ((struct ffa_value){.func = FFA_VERSION_COMPILED});
}
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index c0d8c28..9bedee8 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -485,7 +485,7 @@
*/
switch (func) {
case FFA_VERSION_32:
- *args = api_ffa_version(args->arg1);
+ *args = api_ffa_version(current, args->arg1);
return true;
case FFA_PARTITION_INFO_GET_32: {
struct ffa_uuid uuid;
diff --git a/src/arch/aarch64/plat/ffa/hypervisor.c b/src/arch/aarch64/plat/ffa/hypervisor.c
index 4d0e349..b8489e3 100644
--- a/src/arch/aarch64/plat/ffa/hypervisor.c
+++ b/src/arch/aarch64/plat/ffa/hypervisor.c
@@ -76,6 +76,17 @@
arch_ffa_init();
+ /*
+ * Call FFA_VERSION so the SPMC can store the hypervisor's
+ * version. This may be useful if there is a mismatch of
+ * versions.
+ */
+ ret = arch_other_world_call((struct ffa_value){
+ .func = FFA_VERSION_32, .arg1 = FFA_VERSION_COMPILED});
+ if (ret.func == (uint32_t)FFA_NOT_SUPPORTED) {
+ panic("Hypervisor and SPMC versions are not compatible.\n");
+ }
+
/* Setup TEE VM RX/TX buffers */
other_world_vm->mailbox.send = &other_world_send_buffer;
other_world_vm->mailbox.recv = &other_world_recv_buffer;
diff --git a/src/init.c b/src/init.c
index db05ad9..ab8d8a4 100644
--- a/src/init.c
+++ b/src/init.c
@@ -174,7 +174,7 @@
/* Enable TLB invalidation for VM page table updates. */
mm_vm_enable_invalidation();
- /* Set up message buffers for TEE dispatcher. */
+ /* Perform platform specfic FF-A initialization. */
plat_ffa_init(manifest.ffa_tee_enabled);
dlog_info("Hafnium initialisation completed\n");
diff --git a/src/load.c b/src/load.c
index 501d00e..0aebb54 100644
--- a/src/load.c
+++ b/src/load.c
@@ -187,6 +187,7 @@
dlog_verbose("VM has %d physical interrupts defined in manifest.\n", k);
if (manifest_vm->is_ffa_partition) {
+ vm_locked.vm->ffa_version = manifest_vm->partition.ffa_version;
/* Link rxtx buffers to mailbox */
if (manifest_vm->partition.rxtx.available) {
if (!link_rxtx_to_mailbox(stage1_locked, vm_locked,