Skip to content

Commit a344e25

Browse files
willdeaconoupton
authored andcommitted
KVM: arm64: Use acquire/release to communicate FF-A version negotiation
The pKVM FF-A proxy rejects FF-A requests other than FFA_VERSION until version negotiation is complete, which is signalled by setting the global 'has_version_negotiated' variable. To avoid excessive locking, this variable is checked directly from kvm_host_ffa_handler() in response to an FF-A call, but this can race against another CPU performing the negotiation and potentially lead to reading a torn value (incredibly unlikely for a 'bool') or problematic re-ordering of the accesses to 'has_version_negotiated' and 'hyp_ffa_version' whereby a stale version number could be read by __do_ffa_mem_xfer(). Use acquire/release primitives when writing 'has_version_negotiated' with the version lock held and when reading without the lock held. Cc: Sebastian Ene <[email protected]> Cc: Sudeep Holla <[email protected]> Cc: Quentin Perret <[email protected]> Cc: Oliver Upton <[email protected]> Cc: Marc Zyngier <[email protected]> Fixes: c9c0126 ("KVM: arm64: Trap FFA_VERSION host call in pKVM") Signed-off-by: Will Deacon <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent c8631ea commit a344e25

File tree

1 file changed

+5
-4
lines changed
  • arch/arm64/kvm/hyp/nvhe

1 file changed

+5
-4
lines changed

arch/arm64/kvm/hyp/nvhe/ffa.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -730,10 +730,10 @@ static void do_ffa_version(struct arm_smccc_res *res,
730730
hyp_ffa_version = ffa_req_version;
731731
}
732732

733-
if (hyp_ffa_post_init())
733+
if (hyp_ffa_post_init()) {
734734
res->a0 = FFA_RET_NOT_SUPPORTED;
735-
else {
736-
has_version_negotiated = true;
735+
} else {
736+
smp_store_release(&has_version_negotiated, true);
737737
res->a0 = hyp_ffa_version;
738738
}
739739
unlock:
@@ -809,7 +809,8 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
809809
if (!is_ffa_call(func_id))
810810
return false;
811811

812-
if (!has_version_negotiated && func_id != FFA_VERSION) {
812+
if (func_id != FFA_VERSION &&
813+
!smp_load_acquire(&has_version_negotiated)) {
813814
ffa_to_smccc_error(&res, FFA_RET_INVALID_PARAMETERS);
814815
goto out_handled;
815816
}

0 commit comments

Comments
 (0)