From: Per Larsen <perlarsen@google.com>
To: Marc Zyngier <maz@kernel.org>,
Oliver Upton <oliver.upton@linux.dev>,
Joey Gouly <joey.gouly@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Zenghui Yu <yuzenghui@huawei.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>,
Sudeep Holla <sudeep.holla@arm.com>
Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
linux-kernel@vger.kernel.org, sebastianene@google.com,
qperret@google.com, qwandor@google.com, arve@android.com,
perl@immunant.com, lpieralisi@kernel.org,
kernel-team@android.com, tabba@google.com, james.morse@arm.com,
armellel@google.com, jean-philippe@linaro.org,
ahomescu@google.com, Per Larsen <perlarsen@google.com>
Subject: [PATCH v4 5/5] KVM: arm64: Support FFA_MSG_SEND_DIRECT_REQ2 in host handler
Date: Fri, 16 May 2025 12:14:04 +0000 [thread overview]
Message-ID: <20250516-virtio-msg-ffa-v4-5-580ee70e5081@google.com> (raw)
In-Reply-To: <20250516-virtio-msg-ffa-v4-0-580ee70e5081@google.com>
FF-A 1.2 adds the DIRECT_REQ2 messaging interface which is similar to
the existing FFA_MSG_SEND_DIRECT_{REQ,RESP} functions except that it
uses the SMC calling convention v1.2 which allows calls to use x4-x17 as
argument and return registers. Add support for FFA_MSG_SEND_DIRECT_REQ2
in the host ffa handler.
Signed-off-by: Per Larsen <perlarsen@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 110 +++++++++++++++++++++++++++++++++++++++++-
include/linux/arm_ffa.h | 2 +
2 files changed, 110 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 0b952ace29f6847b4e941262c4c1b05a5bc13e5a..cd75f98bffdb75abd41f9ddc944b8426b93056e4 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -79,6 +79,14 @@ static void ffa_to_smccc_error(struct arm_smccc_res *res, u64 ffa_errno)
};
}
+static void ffa_to_smccc_1_2_error(struct arm_smccc_1_2_regs *regs, u64 ffa_errno)
+{
+ *regs = (struct arm_smccc_1_2_regs) {
+ .a0 = FFA_ERROR,
+ .a2 = ffa_errno,
+ };
+}
+
static void ffa_to_smccc_res_prop(struct arm_smccc_res *res, int ret, u64 prop)
{
if (ret == FFA_RET_SUCCESS) {
@@ -94,6 +102,12 @@ static void ffa_to_smccc_res(struct arm_smccc_res *res, int ret)
ffa_to_smccc_res_prop(res, ret, 0);
}
+static u32 ffa_get_func_id(struct kvm_cpu_context *ctxt)
+{
+ DECLARE_REG(u32, func_id, ctxt, 0);
+ return func_id;
+}
+
static void ffa_set_retval(struct kvm_cpu_context *ctxt,
struct arm_smccc_res *res)
{
@@ -128,6 +142,54 @@ static void ffa_set_retval(struct kvm_cpu_context *ctxt,
}
}
+static void ffa_set_retval_smccc_1_2(struct kvm_cpu_context *ctxt,
+ struct arm_smccc_1_2_regs *regs)
+{
+ cpu_reg(ctxt, 0) = regs->a0;
+ cpu_reg(ctxt, 1) = regs->a1;
+ cpu_reg(ctxt, 2) = regs->a2;
+ cpu_reg(ctxt, 3) = regs->a3;
+ cpu_reg(ctxt, 4) = regs->a4;
+ cpu_reg(ctxt, 5) = regs->a5;
+ cpu_reg(ctxt, 6) = regs->a6;
+ cpu_reg(ctxt, 7) = regs->a7;
+ cpu_reg(ctxt, 8) = regs->a8;
+ cpu_reg(ctxt, 9) = regs->a9;
+ cpu_reg(ctxt, 10) = regs->a10;
+ cpu_reg(ctxt, 11) = regs->a11;
+ cpu_reg(ctxt, 12) = regs->a12;
+ cpu_reg(ctxt, 13) = regs->a13;
+ cpu_reg(ctxt, 14) = regs->a14;
+ cpu_reg(ctxt, 15) = regs->a15;
+ cpu_reg(ctxt, 16) = regs->a16;
+ cpu_reg(ctxt, 17) = regs->a17;
+}
+
+/*
+ * Must a given FFA function use the SMC calling convention v1.2?
+ */
+static bool ffa_call_needs_smccc_1_2(u64 func_id)
+{
+ switch (func_id) {
+ case FFA_MSG_SEND_DIRECT_REQ2:
+ case FFA_MSG_SEND_DIRECT_RESP2:
+ case FFA_PARTITION_INFO_GET_REGS:
+ return true;
+ }
+
+ return false;
+}
+
+static void ffa_set_retval_smccc_1_x(struct kvm_cpu_context *ctxt,
+ struct arm_smccc_res *res,
+ struct arm_smccc_1_2_regs *regs)
+{
+ if (ffa_call_needs_smccc_1_2(ffa_get_func_id(ctxt)))
+ ffa_set_retval_smccc_1_2(ctxt, regs);
+ else
+ ffa_set_retval(ctxt, res);
+}
+
/* Call SMC64 using SMCCC 1.2 if hyp negotiated FF-A 1.2 falling back to 1.1 */
static void arm_smccc_1_x_smc(u64 func_id, u64 a1, u64 a2, u64 a3,
u64 a4, u64 a5, u64 a6, u64 a7,
@@ -683,7 +745,6 @@ static bool ffa_call_supported(u64 func_id)
case FFA_NOTIFICATION_GET:
case FFA_NOTIFICATION_INFO_GET:
/* Unimplemented interfaces added in FF-A 1.2 */
- case FFA_MSG_SEND_DIRECT_REQ2:
case FFA_MSG_SEND_DIRECT_RESP2:
case FFA_CONSOLE_LOG:
case FFA_PARTITION_INFO_GET_REGS:
@@ -852,9 +913,47 @@ static void do_ffa_part_get(struct arm_smccc_res *res,
hyp_spin_unlock(&host_buffers.lock);
}
+static void do_ffa_direct_msg2(struct arm_smccc_1_2_regs *regs,
+ struct kvm_cpu_context *ctxt,
+ u64 vm_handle)
+{
+ DECLARE_REG(u32, func_id, ctxt, 0);
+ DECLARE_REG(u32, endp, ctxt, 1);
+ DECLARE_REG(u64, uuid_lo, ctxt, 2);
+ DECLARE_REG(u64, uuid_hi, ctxt, 3);
+ DECLARE_REG(u64, x4, ctxt, 4);
+ DECLARE_REG(u64, x5, ctxt, 5);
+ DECLARE_REG(u64, x6, ctxt, 6);
+ DECLARE_REG(u64, x7, ctxt, 7);
+ DECLARE_REG(u64, x8, ctxt, 8);
+ DECLARE_REG(u64, x9, ctxt, 9);
+ DECLARE_REG(u64, x10, ctxt, 10);
+ DECLARE_REG(u64, x11, ctxt, 11);
+ DECLARE_REG(u64, x12, ctxt, 12);
+ DECLARE_REG(u64, x13, ctxt, 13);
+ DECLARE_REG(u64, x14, ctxt, 14);
+ DECLARE_REG(u64, x15, ctxt, 15);
+ DECLARE_REG(u64, x16, ctxt, 16);
+ DECLARE_REG(u64, x17, ctxt, 17);
+
+ if (FIELD_GET(FFA_SRC_ENDPOINT_MASK, endp) != vm_handle) {
+ ffa_to_smccc_1_2_error(regs, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ struct arm_smccc_1_2_regs args = {
+ func_id, endp, uuid_lo, uuid_hi,
+ x4, x5, x6, x7, x8, x9, x10,
+ x11, x12, x13, x14, x15, x16, x17
+ };
+
+ arm_smccc_1_2_smc(&args, regs);
+}
+
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
struct arm_smccc_res res;
+ struct arm_smccc_1_2_regs regs;
/*
* There's no way we can tell what a non-standard SMC call might
@@ -910,14 +1009,21 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
case FFA_PARTITION_INFO_GET:
do_ffa_part_get(&res, host_ctxt);
goto out_handled;
+ case FFA_MSG_SEND_DIRECT_REQ2:
+ if (hyp_ffa_version >= FFA_VERSION_1_2) {
+ do_ffa_direct_msg2(®s, host_ctxt, HOST_FFA_ID);
+ goto out_handled;
+ }
+ goto out_not_supported;
}
if (ffa_call_supported(func_id))
return false; /* Pass through */
+out_not_supported:
ffa_to_smccc_error(&res, FFA_RET_NOT_SUPPORTED);
out_handled:
- ffa_set_retval(host_ctxt, &res);
+ ffa_set_retval_smccc_1_x(host_ctxt, &res, ®s);
return true;
}
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
index c0dd6183d956043192114a522b7eef465e7078ac..82a35a3b22de426f7e9a8894e76fdf1e933b3d6b 100644
--- a/include/linux/arm_ffa.h
+++ b/include/linux/arm_ffa.h
@@ -269,6 +269,8 @@ bool ffa_partition_check_property(struct ffa_device *dev, u32 property)
(ffa_partition_check_property(dev, FFA_PARTITION_DIRECT_REQ2_RECV) && \
!dev->mode_32bit)
+#define FFA_SRC_ENDPOINT_MASK GENMASK(31, 16)
+
/* For use with FFA_MSG_SEND_DIRECT_{REQ,RESP} which pass data via registers */
struct ffa_send_direct_data {
unsigned long data0; /* w3/x3 */
--
2.49.0.1101.gccaa498523-goog
WARNING: multiple messages have this Message-ID (diff)
From: Per Larsen via B4 Relay <devnull+perlarsen.google.com@kernel.org>
To: Marc Zyngier <maz@kernel.org>,
Oliver Upton <oliver.upton@linux.dev>,
Joey Gouly <joey.gouly@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Zenghui Yu <yuzenghui@huawei.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>,
Sudeep Holla <sudeep.holla@arm.com>
Cc: linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
linux-kernel@vger.kernel.org, sebastianene@google.com,
qperret@google.com, qwandor@google.com, arve@android.com,
perl@immunant.com, lpieralisi@kernel.org,
kernel-team@android.com, tabba@google.com, james.morse@arm.com,
armellel@google.com, jean-philippe@linaro.org,
ahomescu@google.com, Per Larsen <perlarsen@google.com>
Subject: [PATCH v4 5/5] KVM: arm64: Support FFA_MSG_SEND_DIRECT_REQ2 in host handler
Date: Fri, 16 May 2025 12:14:04 +0000 [thread overview]
Message-ID: <20250516-virtio-msg-ffa-v4-5-580ee70e5081@google.com> (raw)
In-Reply-To: <20250516-virtio-msg-ffa-v4-0-580ee70e5081@google.com>
From: Per Larsen <perlarsen@google.com>
FF-A 1.2 adds the DIRECT_REQ2 messaging interface which is similar to
the existing FFA_MSG_SEND_DIRECT_{REQ,RESP} functions except that it
uses the SMC calling convention v1.2 which allows calls to use x4-x17 as
argument and return registers. Add support for FFA_MSG_SEND_DIRECT_REQ2
in the host ffa handler.
Signed-off-by: Per Larsen <perlarsen@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 110 +++++++++++++++++++++++++++++++++++++++++-
include/linux/arm_ffa.h | 2 +
2 files changed, 110 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 0b952ace29f6847b4e941262c4c1b05a5bc13e5a..cd75f98bffdb75abd41f9ddc944b8426b93056e4 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -79,6 +79,14 @@ static void ffa_to_smccc_error(struct arm_smccc_res *res, u64 ffa_errno)
};
}
+static void ffa_to_smccc_1_2_error(struct arm_smccc_1_2_regs *regs, u64 ffa_errno)
+{
+ *regs = (struct arm_smccc_1_2_regs) {
+ .a0 = FFA_ERROR,
+ .a2 = ffa_errno,
+ };
+}
+
static void ffa_to_smccc_res_prop(struct arm_smccc_res *res, int ret, u64 prop)
{
if (ret == FFA_RET_SUCCESS) {
@@ -94,6 +102,12 @@ static void ffa_to_smccc_res(struct arm_smccc_res *res, int ret)
ffa_to_smccc_res_prop(res, ret, 0);
}
+static u32 ffa_get_func_id(struct kvm_cpu_context *ctxt)
+{
+ DECLARE_REG(u32, func_id, ctxt, 0);
+ return func_id;
+}
+
static void ffa_set_retval(struct kvm_cpu_context *ctxt,
struct arm_smccc_res *res)
{
@@ -128,6 +142,54 @@ static void ffa_set_retval(struct kvm_cpu_context *ctxt,
}
}
+static void ffa_set_retval_smccc_1_2(struct kvm_cpu_context *ctxt,
+ struct arm_smccc_1_2_regs *regs)
+{
+ cpu_reg(ctxt, 0) = regs->a0;
+ cpu_reg(ctxt, 1) = regs->a1;
+ cpu_reg(ctxt, 2) = regs->a2;
+ cpu_reg(ctxt, 3) = regs->a3;
+ cpu_reg(ctxt, 4) = regs->a4;
+ cpu_reg(ctxt, 5) = regs->a5;
+ cpu_reg(ctxt, 6) = regs->a6;
+ cpu_reg(ctxt, 7) = regs->a7;
+ cpu_reg(ctxt, 8) = regs->a8;
+ cpu_reg(ctxt, 9) = regs->a9;
+ cpu_reg(ctxt, 10) = regs->a10;
+ cpu_reg(ctxt, 11) = regs->a11;
+ cpu_reg(ctxt, 12) = regs->a12;
+ cpu_reg(ctxt, 13) = regs->a13;
+ cpu_reg(ctxt, 14) = regs->a14;
+ cpu_reg(ctxt, 15) = regs->a15;
+ cpu_reg(ctxt, 16) = regs->a16;
+ cpu_reg(ctxt, 17) = regs->a17;
+}
+
+/*
+ * Must a given FFA function use the SMC calling convention v1.2?
+ */
+static bool ffa_call_needs_smccc_1_2(u64 func_id)
+{
+ switch (func_id) {
+ case FFA_MSG_SEND_DIRECT_REQ2:
+ case FFA_MSG_SEND_DIRECT_RESP2:
+ case FFA_PARTITION_INFO_GET_REGS:
+ return true;
+ }
+
+ return false;
+}
+
+static void ffa_set_retval_smccc_1_x(struct kvm_cpu_context *ctxt,
+ struct arm_smccc_res *res,
+ struct arm_smccc_1_2_regs *regs)
+{
+ if (ffa_call_needs_smccc_1_2(ffa_get_func_id(ctxt)))
+ ffa_set_retval_smccc_1_2(ctxt, regs);
+ else
+ ffa_set_retval(ctxt, res);
+}
+
/* Call SMC64 using SMCCC 1.2 if hyp negotiated FF-A 1.2 falling back to 1.1 */
static void arm_smccc_1_x_smc(u64 func_id, u64 a1, u64 a2, u64 a3,
u64 a4, u64 a5, u64 a6, u64 a7,
@@ -683,7 +745,6 @@ static bool ffa_call_supported(u64 func_id)
case FFA_NOTIFICATION_GET:
case FFA_NOTIFICATION_INFO_GET:
/* Unimplemented interfaces added in FF-A 1.2 */
- case FFA_MSG_SEND_DIRECT_REQ2:
case FFA_MSG_SEND_DIRECT_RESP2:
case FFA_CONSOLE_LOG:
case FFA_PARTITION_INFO_GET_REGS:
@@ -852,9 +913,47 @@ static void do_ffa_part_get(struct arm_smccc_res *res,
hyp_spin_unlock(&host_buffers.lock);
}
+static void do_ffa_direct_msg2(struct arm_smccc_1_2_regs *regs,
+ struct kvm_cpu_context *ctxt,
+ u64 vm_handle)
+{
+ DECLARE_REG(u32, func_id, ctxt, 0);
+ DECLARE_REG(u32, endp, ctxt, 1);
+ DECLARE_REG(u64, uuid_lo, ctxt, 2);
+ DECLARE_REG(u64, uuid_hi, ctxt, 3);
+ DECLARE_REG(u64, x4, ctxt, 4);
+ DECLARE_REG(u64, x5, ctxt, 5);
+ DECLARE_REG(u64, x6, ctxt, 6);
+ DECLARE_REG(u64, x7, ctxt, 7);
+ DECLARE_REG(u64, x8, ctxt, 8);
+ DECLARE_REG(u64, x9, ctxt, 9);
+ DECLARE_REG(u64, x10, ctxt, 10);
+ DECLARE_REG(u64, x11, ctxt, 11);
+ DECLARE_REG(u64, x12, ctxt, 12);
+ DECLARE_REG(u64, x13, ctxt, 13);
+ DECLARE_REG(u64, x14, ctxt, 14);
+ DECLARE_REG(u64, x15, ctxt, 15);
+ DECLARE_REG(u64, x16, ctxt, 16);
+ DECLARE_REG(u64, x17, ctxt, 17);
+
+ if (FIELD_GET(FFA_SRC_ENDPOINT_MASK, endp) != vm_handle) {
+ ffa_to_smccc_1_2_error(regs, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ struct arm_smccc_1_2_regs args = {
+ func_id, endp, uuid_lo, uuid_hi,
+ x4, x5, x6, x7, x8, x9, x10,
+ x11, x12, x13, x14, x15, x16, x17
+ };
+
+ arm_smccc_1_2_smc(&args, regs);
+}
+
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
struct arm_smccc_res res;
+ struct arm_smccc_1_2_regs regs;
/*
* There's no way we can tell what a non-standard SMC call might
@@ -910,14 +1009,21 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
case FFA_PARTITION_INFO_GET:
do_ffa_part_get(&res, host_ctxt);
goto out_handled;
+ case FFA_MSG_SEND_DIRECT_REQ2:
+ if (hyp_ffa_version >= FFA_VERSION_1_2) {
+ do_ffa_direct_msg2(®s, host_ctxt, HOST_FFA_ID);
+ goto out_handled;
+ }
+ goto out_not_supported;
}
if (ffa_call_supported(func_id))
return false; /* Pass through */
+out_not_supported:
ffa_to_smccc_error(&res, FFA_RET_NOT_SUPPORTED);
out_handled:
- ffa_set_retval(host_ctxt, &res);
+ ffa_set_retval_smccc_1_x(host_ctxt, &res, ®s);
return true;
}
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
index c0dd6183d956043192114a522b7eef465e7078ac..82a35a3b22de426f7e9a8894e76fdf1e933b3d6b 100644
--- a/include/linux/arm_ffa.h
+++ b/include/linux/arm_ffa.h
@@ -269,6 +269,8 @@ bool ffa_partition_check_property(struct ffa_device *dev, u32 property)
(ffa_partition_check_property(dev, FFA_PARTITION_DIRECT_REQ2_RECV) && \
!dev->mode_32bit)
+#define FFA_SRC_ENDPOINT_MASK GENMASK(31, 16)
+
/* For use with FFA_MSG_SEND_DIRECT_{REQ,RESP} which pass data via registers */
struct ffa_send_direct_data {
unsigned long data0; /* w3/x3 */
--
2.49.0.1101.gccaa498523-goog
next prev parent reply other threads:[~2025-05-16 12:14 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-16 12:13 [PATCH v4 0/5] KVM: arm64: Support FF-A 1.2 and SEND_DIRECT2 ABI Per Larsen
2025-05-16 12:13 ` Per Larsen via B4 Relay
2025-05-16 12:14 ` [PATCH v4 1/5] KVM: arm64: Restrict FF-A host version renegotiation Per Larsen
2025-05-16 12:14 ` Per Larsen via B4 Relay
2025-05-29 9:54 ` Will Deacon
2025-05-16 12:14 ` [PATCH v4 2/5] KVM: arm64: Zero x4-x7 in ffa_set_retval Per Larsen
2025-05-16 12:14 ` Per Larsen via B4 Relay
2025-05-29 12:17 ` Will Deacon
2025-05-16 12:14 ` [PATCH v4 3/5] KVM: arm64: Mark FFA_NOTIFICATION_* calls as unsupported Per Larsen
2025-05-16 12:14 ` Per Larsen via B4 Relay
2025-05-29 12:05 ` Will Deacon
2025-05-16 12:14 ` [PATCH v4 4/5] KVM: arm64: Bump the supported version of FF-A to 1.2 Per Larsen
2025-05-16 12:14 ` Per Larsen via B4 Relay
2025-05-16 12:14 ` Per Larsen [this message]
2025-05-16 12:14 ` [PATCH v4 5/5] KVM: arm64: Support FFA_MSG_SEND_DIRECT_REQ2 in host handler Per Larsen via B4 Relay
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=20250516-virtio-msg-ffa-v4-5-580ee70e5081@google.com \
--to=perlarsen@google.com \
--cc=ahomescu@google.com \
--cc=armellel@google.com \
--cc=arve@android.com \
--cc=catalin.marinas@arm.com \
--cc=james.morse@arm.com \
--cc=jean-philippe@linaro.org \
--cc=joey.gouly@arm.com \
--cc=kernel-team@android.com \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lpieralisi@kernel.org \
--cc=maz@kernel.org \
--cc=oliver.upton@linux.dev \
--cc=perl@immunant.com \
--cc=qperret@google.com \
--cc=qwandor@google.com \
--cc=sebastianene@google.com \
--cc=sudeep.holla@arm.com \
--cc=suzuki.poulose@arm.com \
--cc=tabba@google.com \
--cc=will@kernel.org \
--cc=yuzenghui@huawei.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.