diff mbox series

[v2] KVM: arm64: FFA: Release hyp rx buffer

Message ID 20240611175317.1220842-1-vdonnefort@google.com (mailing list archive)
State New, archived
Headers show
Series [v2] KVM: arm64: FFA: Release hyp rx buffer | expand

Commit Message

Vincent Donnefort June 11, 2024, 5:53 p.m. UTC
According to the FF-A spec (Buffer states and ownership), after a
producer has written into a buffer, it is "full" and now owned by the
consumer. The producer won't be able to use that buffer, until the
consumer hands it over with an invocation such as RX_RELEASE.

It is clear in the following paragraph (Transfer of buffer ownership),
that MEM_RETRIEVE_RESP is transferring the ownership from producer (in
our case SPM) to consumer (hypervisor). RX_RELEASE is therefore
mandatory here.

It is less clear though what is happening with MEM_FRAG_TX. But this
invocation, as a response to MEM_FRAG_RX writes into the same hypervisor
RX buffer (see paragraph "Transmission of transaction descriptor in
fragments"). Also this is matching the TF-A implementation where the RX
buffer is marked "full" during a MEM_FRAG_RX.

Release the RX hypervisor buffer in those two cases. This will unblock
later invocations using this buffer which would otherwise fail.
(RETRIEVE_REQ, MEM_FRAG_RX and PARTITION_INFO_GET).

Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>

---

v1 -> v2: 
  * Use FF-A paragraph names instead of numbers
  * Reword commit 
  * Collect Reviewed-by 


base-commit: 6d69b6c12fce479fde7bc06f686212451688a102

Comments

Marc Zyngier June 11, 2024, 6:49 p.m. UTC | #1
On Tue, 11 Jun 2024 18:53:17 +0100, Vincent Donnefort wrote:
> According to the FF-A spec (Buffer states and ownership), after a
> producer has written into a buffer, it is "full" and now owned by the
> consumer. The producer won't be able to use that buffer, until the
> consumer hands it over with an invocation such as RX_RELEASE.
> 
> It is clear in the following paragraph (Transfer of buffer ownership),
> that MEM_RETRIEVE_RESP is transferring the ownership from producer (in
> our case SPM) to consumer (hypervisor). RX_RELEASE is therefore
> mandatory here.
> 
> [...]

Applied to fixes, thanks!

[1/1] KVM: arm64: FFA: Release hyp rx buffer
      commit: d66e50beb91114f387bd798a371384b2a245e8cc

Cheers,

	M.
diff mbox series

Patch

diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 02746f9d0980..efb053af331c 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -177,6 +177,14 @@  static void ffa_retrieve_req(struct arm_smccc_res *res, u32 len)
 			  res);
 }
 
+static void ffa_rx_release(struct arm_smccc_res *res)
+{
+	arm_smccc_1_1_smc(FFA_RX_RELEASE,
+			  0, 0,
+			  0, 0, 0, 0, 0,
+			  res);
+}
+
 static void do_ffa_rxtx_map(struct arm_smccc_res *res,
 			    struct kvm_cpu_context *ctxt)
 {
@@ -543,16 +551,19 @@  static void do_ffa_mem_reclaim(struct arm_smccc_res *res,
 	if (WARN_ON(offset > len ||
 		    fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE)) {
 		ret = FFA_RET_ABORTED;
+		ffa_rx_release(res);
 		goto out_unlock;
 	}
 
 	if (len > ffa_desc_buf.len) {
 		ret = FFA_RET_NO_MEMORY;
+		ffa_rx_release(res);
 		goto out_unlock;
 	}
 
 	buf = ffa_desc_buf.buf;
 	memcpy(buf, hyp_buffers.rx, fraglen);
+	ffa_rx_release(res);
 
 	for (fragoff = fraglen; fragoff < len; fragoff += fraglen) {
 		ffa_mem_frag_rx(res, handle_lo, handle_hi, fragoff);
@@ -563,6 +574,7 @@  static void do_ffa_mem_reclaim(struct arm_smccc_res *res,
 
 		fraglen = res->a3;
 		memcpy((void *)buf + fragoff, hyp_buffers.rx, fraglen);
+		ffa_rx_release(res);
 	}
 
 	ffa_mem_reclaim(res, handle_lo, handle_hi, flags);