feat: restrict `FFA_VERSION` calls

FF-A v1.2 restricts the use of the `FFA_VERSION` ABI. The FF-A version
can only be set by calls to `FFA_VERSION` before calls to any other
ABIs.

BREAKING CHANGE: Attempts to change the FF-A version after calls to
other FF-A ABIs will fail. Calls to `FFA_VERSION` that do not change the
version are still allowed.

Some tests are now failing because of this breaking change. They will be
fixed in future commits.

Change-Id: I3e24ff9c5f3eb6743c6373c97f378655fc8acbad
Signed-off-by: Karl Meakin <karl.meakin@arm.com>
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index 311c075..0977819 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -859,9 +859,11 @@
 static bool hvc_smc_handler(struct ffa_value args, struct vcpu *vcpu,
 			    struct vcpu **next)
 {
+	const uint32_t func = args.func;
+
 	/* Do not expect PSCI calls emitted from within the secure world. */
 #if SECURE_WORLD == 0
-	if (psci_handler(vcpu, args.func, args.arg1, args.arg2, args.arg3,
+	if (psci_handler(vcpu, func, args.arg1, args.arg2, args.arg3,
 			 &vcpu->regs.r[0], next)) {
 		return true;
 	}
@@ -879,6 +881,13 @@
 			plat_ffa_sri_trigger_if_delayed(vcpu->cpu);
 		}
 #endif
+		if (func != FFA_VERSION_32) {
+			struct vm_locked vm_locked = vm_lock(vcpu->vm);
+
+			vm_locked.vm->ffa_version_negotiated = true;
+			vm_unlock(&vm_locked);
+		}
+
 		arch_regs_set_retval(&vcpu->regs, args);
 		vcpu_update_virtual_interrupts(*next);
 		return true;