From: Jamie Nguyen <jamien@nvidia.com>
To: Lorenzo Pieralisi <lpieralisi@kernel.org>,
Hanjun Guo <guohanjun@huawei.com>,
Sudeep Holla <sudeep.holla@kernel.org>,
"Catalin Marinas" <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>,
"Rafael J . Wysocki" <rafael@kernel.org>
Cc: Len Brown <lenb@kernel.org>, Dat Mach <dmach@nvidia.com>,
<linux-acpi@vger.kernel.org>,
<linux-arm-kernel@lists.infradead.org>,
<linux-kernel@vger.kernel.org>, Jamie Nguyen <jamien@nvidia.com>
Subject: [RFC PATCH 1/3] firmware: arm_ffa: Split the response out of ffa_msg_send_direct_req2()
Date: Wed, 29 Jul 2026 10:56:36 -0700 [thread overview]
Message-ID: <20260729175638.3796440-2-jamien@nvidia.com> (raw)
In-Reply-To: <20260729175638.3796440-1-jamien@nvidia.com>
ffa_msg_send_direct_req2() uses one buffer for both the request and the
response, and it only ever reports a callee side FFA_ERROR as a translated
errno. The ACPI FFH Operation Region handler added later in this series
can work with neither. It has to hand every response register back to AML,
including on the paths where the call failed.
Move the body into __ffa_msg_send_direct_req2(). It writes the response to
a buffer of its own, returns X1-X3 through @resp_regs, and separates three
outcomes: success, a callee that returned FFA_ERROR (-EIO, with the FF-A
error code left in @resp_regs[1]), and anything else (-EPROTO).
ffa_msg_send_direct_req2() sits on top of that as a wrapper. It copies to
the caller's buffer only on success and returns the same errnos it did
before, so ffa_sync_send_receive2() and its users are untouched.
No functional change.
Co-developed-by: Dat Mach <dmach@nvidia.com>
Signed-off-by: Dat Mach <dmach@nvidia.com>
Signed-off-by: Jamie Nguyen <jamien@nvidia.com>
---
drivers/firmware/arm_ffa/driver.c | 51 ++++++++++++++++++++++++++-----
1 file changed, 44 insertions(+), 7 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 8654b3365c9b6..3236cd0a731ab 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -560,8 +560,20 @@ static int ffa_msg_send2(struct ffa_device *dev, u16 src_id, void *buf, size_t s
return retval;
}
-static int ffa_msg_send_direct_req2(u16 src_id, u16 dst_id, const uuid_t *uuid,
- struct ffa_send_direct_data2 *data)
+/*
+ * Sends @req and reports the callee's X1-X3 through @resp_regs and its
+ * X4-X17 through @resp, both unconditionally, so that a caller bound by
+ * DEN0048D section 2.3.1.2 can copy every register back to AML even when the
+ * callee returned FFA_ERROR. Keeping the response out of @req leaves the
+ * caller free to decide when, if ever, to overwrite its own buffer. Returns
+ * -EIO for FFA_ERROR (the FF-A error code is left in @resp_regs[1] as X2) and
+ * -EPROTO for an unexpected response; both mean the call was made. Callers
+ * that only need an errno should use ffa_msg_send_direct_req2().
+ */
+static int __ffa_msg_send_direct_req2(u16 src_id, u16 dst_id, const uuid_t *uuid,
+ const struct ffa_send_direct_data2 *req,
+ struct ffa_send_direct_data2 *resp,
+ u64 resp_regs[3])
{
u32 src_dst_ids = PACK_TARGET_INFO(src_id, dst_id);
union {
@@ -574,21 +586,46 @@ static int ffa_msg_send_direct_req2(u16 src_id, u16 dst_id, const uuid_t *uuid,
.a2 = le64_to_cpu(uuid_regs.regs[0]),
.a3 = le64_to_cpu(uuid_regs.regs[1]),
};
- memcpy((void *)&args + offsetof(ffa_value_t, a4), data, sizeof(*data));
+ memcpy((void *)&args + offsetof(ffa_value_t, a4), req, sizeof(*req));
invoke_ffa_fn(args, &ret);
ffa_msg_send_wait_for_completion(&ret);
+ resp_regs[0] = ret.a1;
+ resp_regs[1] = ret.a2;
+ resp_regs[2] = ret.a3;
+ memcpy(resp, (void *)&ret + offsetof(ffa_value_t, a4), sizeof(*resp));
+
if (ret.a0 == FFA_ERROR)
- return ffa_to_linux_errno((int)ret.a2);
+ return -EIO;
+
+ if (ret.a0 == FFA_MSG_SEND_DIRECT_RESP2)
+ return 0;
+
+ return -EPROTO;
+}
- if (ret.a0 == FFA_MSG_SEND_DIRECT_RESP2) {
- memcpy(data, (void *)&ret + offsetof(ffa_value_t, a4), sizeof(*data));
+static int ffa_msg_send_direct_req2(u16 src_id, u16 dst_id, const uuid_t *uuid,
+ struct ffa_send_direct_data2 *data)
+{
+ struct ffa_send_direct_data2 resp;
+ u64 resp_regs[3];
+ int ret;
+
+ ret = __ffa_msg_send_direct_req2(src_id, dst_id, uuid, data, &resp,
+ resp_regs);
+ if (!ret) {
+ *data = resp;
return 0;
}
- return -EINVAL;
+ if (ret == -EIO)
+ return ffa_to_linux_errno((int)resp_regs[1]);
+ if (ret == -EPROTO)
+ return -EINVAL;
+
+ return ret;
}
static int ffa_mem_first_frag(u32 func_id, phys_addr_t buf, u32 buf_sz,
--
2.43.0
next prev parent reply other threads:[~2026-07-29 17:57 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-29 17:56 [RFC PATCH 0/3] ACPI: arm64: FFH Operation Region support for FF-A (offset 2) Jamie Nguyen
2026-07-29 17:56 ` Jamie Nguyen [this message]
2026-07-29 17:56 ` [RFC PATCH 2/3] ACPI: arm64: Add support for the FF-A FFH Operation Region " Jamie Nguyen
2026-07-29 17:56 ` [RFC PATCH 3/3] firmware: arm_ffa: Back the ACPI FF-A FFH Operation Region Jamie Nguyen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260729175638.3796440-2-jamien@nvidia.com \
--to=jamien@nvidia.com \
--cc=catalin.marinas@arm.com \
--cc=dmach@nvidia.com \
--cc=guohanjun@huawei.com \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lpieralisi@kernel.org \
--cc=rafael@kernel.org \
--cc=sudeep.holla@kernel.org \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox