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 | 24 +++++++++++++++++++++++-
include/linux/arm_ffa.h | 2 ++
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 79d834120a3f3d26e17e9170c60012b60c6f5a5e..21225988a9365219ccfd69e8e599d7403b5cdf05 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -679,7 +679,6 @@ static bool ffa_call_supported(u64 func_id)
case FFA_NOTIFICATION_GET:
case FFA_NOTIFICATION_INFO_GET:
/* Optional interfaces added in FF-A 1.2 */
- case FFA_MSG_SEND_DIRECT_REQ2: /* Optional per 7.5.1 */
case FFA_MSG_SEND_DIRECT_RESP2: /* Optional per 7.5.1 */
case FFA_CONSOLE_LOG: /* Optional per 13.1: not in Table 13.1 */
case FFA_PARTITION_INFO_GET_REGS: /* Optional for virtual instances per 13.1 */
@@ -862,6 +861,22 @@ static void do_ffa_part_get(struct arm_smccc_1_2_regs *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, endp, ctxt, 1);
+
+ struct arm_smccc_1_2_regs *args = (void *)&ctxt->regs.regs[0];
+
+ if (FIELD_GET(FFA_SRC_ENDPOINT_MASK, endp) != vm_handle) {
+ ffa_to_smccc_error(regs, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ arm_smccc_1_2_smc(args, regs);
+}
+
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
struct arm_smccc_1_2_regs res;
@@ -920,11 +935,18 @@ 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(&res, 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);
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
index 2b760bede9c0a4bcb58bf697681c32e77c08a5d9..db63a96190545c9f65943909de2d73cf8e7b9615 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.50.0.727.gbf7dc18ff4-goog
On Tue, Jul 01, 2025 at 10:06:38PM +0000, Per Larsen via B4 Relay wrote:
> 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 | 24 +++++++++++++++++++++++-
> include/linux/arm_ffa.h | 2 ++
> 2 files changed, 25 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
> index 79d834120a3f3d26e17e9170c60012b60c6f5a5e..21225988a9365219ccfd69e8e599d7403b5cdf05 100644
> --- a/arch/arm64/kvm/hyp/nvhe/ffa.c
> +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
> @@ -679,7 +679,6 @@ static bool ffa_call_supported(u64 func_id)
> case FFA_NOTIFICATION_GET:
> case FFA_NOTIFICATION_INFO_GET:
> /* Optional interfaces added in FF-A 1.2 */
> - case FFA_MSG_SEND_DIRECT_REQ2: /* Optional per 7.5.1 */
I think that's the only change needed. In fact, maybe just don't add it
in the earlier patch?
> case FFA_MSG_SEND_DIRECT_RESP2: /* Optional per 7.5.1 */
> case FFA_CONSOLE_LOG: /* Optional per 13.1: not in Table 13.1 */
> case FFA_PARTITION_INFO_GET_REGS: /* Optional for virtual instances per 13.1 */
> @@ -862,6 +861,22 @@ static void do_ffa_part_get(struct arm_smccc_1_2_regs *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, endp, ctxt, 1);
> +
> + struct arm_smccc_1_2_regs *args = (void *)&ctxt->regs.regs[0];
> +
> + if (FIELD_GET(FFA_SRC_ENDPOINT_MASK, endp) != vm_handle) {
> + ffa_to_smccc_error(regs, FFA_RET_INVALID_PARAMETERS);
> + return;
> + }
Why do we care about checking the src id? We don't check that for
FFA_MSG_SEND_DIRECT_REQ and I don't think we need to care about it here
either.
Will
On 7/18/25 6:53 AM, Will Deacon wrote:
> On Tue, Jul 01, 2025 at 10:06:38PM +0000, Per Larsen via B4 Relay wrote:
>> 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 | 24 +++++++++++++++++++++++-
>> include/linux/arm_ffa.h | 2 ++
>> 2 files changed, 25 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
>> index 79d834120a3f3d26e17e9170c60012b60c6f5a5e..21225988a9365219ccfd69e8e599d7403b5cdf05 100644
>> --- a/arch/arm64/kvm/hyp/nvhe/ffa.c
>> +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
>> @@ -679,7 +679,6 @@ static bool ffa_call_supported(u64 func_id)
>> case FFA_NOTIFICATION_GET:
>> case FFA_NOTIFICATION_INFO_GET:
>> /* Optional interfaces added in FF-A 1.2 */
>> - case FFA_MSG_SEND_DIRECT_REQ2: /* Optional per 7.5.1 */
>
> I think that's the only change needed. In fact, maybe just don't add it
> in the earlier patch?
>
>> case FFA_MSG_SEND_DIRECT_RESP2: /* Optional per 7.5.1 */
>> case FFA_CONSOLE_LOG: /* Optional per 13.1: not in Table 13.1 */
>> case FFA_PARTITION_INFO_GET_REGS: /* Optional for virtual instances per 13.1 */
>> @@ -862,6 +861,22 @@ static void do_ffa_part_get(struct arm_smccc_1_2_regs *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, endp, ctxt, 1);
>> +
>> + struct arm_smccc_1_2_regs *args = (void *)&ctxt->regs.regs[0];
>> +
>> + if (FIELD_GET(FFA_SRC_ENDPOINT_MASK, endp) != vm_handle) {
>> + ffa_to_smccc_error(regs, FFA_RET_INVALID_PARAMETERS);
>> + return;
>> + }
>
> Why do we care about checking the src id? We don't check that for
> FFA_MSG_SEND_DIRECT_REQ and I don't think we need to care about it here
> either.
FFA_MSG_SEND_DIRECT_REQ is handled by do_ffa_direct_msg [0] (in the
android common kernels, I'm not aware of efforts to upstream this).
I patterned the check in do_ffa_direct_msg2 off the checking done in
do_ffa_direct_msg. I pressume your reasoning is that this check can
never fail since we pass in HOST_FFA_ID in kvm_host_ffa_handler. My
thinking was that we do need to validate the source ID once we start
using this function for requests that come from a guest VM. I could
of course add the check in an android-specific patch, WDYT is best?
Also note that since do_ffa_direct_msg was switched to use SMCCC 1.2, I
think it can handle both FFA_MSG_SEND_DIRECT_REQ and
FFA_MSG_SEND_DIRECT_REQ2. If you agree, should we upstream
do_ffa_direct_msg and use it to handle both of these direct requests?
[0]
https://cs.android.com/android/kernel/superproject/+/common-android16-6.12:common/arch/arm64/kvm/hyp/nvhe/ffa.c;l=1446
Thanks,
Per
On Mon, Jul 21, 2025 at 03:43:42PM -0700, Per Larsen wrote:
>
>
> On 7/18/25 6:53 AM, Will Deacon wrote:
> > On Tue, Jul 01, 2025 at 10:06:38PM +0000, Per Larsen via B4 Relay wrote:
> > > 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 | 24 +++++++++++++++++++++++-
> > > include/linux/arm_ffa.h | 2 ++
> > > 2 files changed, 25 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
> > > index 79d834120a3f3d26e17e9170c60012b60c6f5a5e..21225988a9365219ccfd69e8e599d7403b5cdf05 100644
> > > --- a/arch/arm64/kvm/hyp/nvhe/ffa.c
> > > +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
> > > @@ -679,7 +679,6 @@ static bool ffa_call_supported(u64 func_id)
> > > case FFA_NOTIFICATION_GET:
> > > case FFA_NOTIFICATION_INFO_GET:
> > > /* Optional interfaces added in FF-A 1.2 */
> > > - case FFA_MSG_SEND_DIRECT_REQ2: /* Optional per 7.5.1 */
> >
> > I think that's the only change needed. In fact, maybe just don't add it
> > in the earlier patch?
> >
> > > case FFA_MSG_SEND_DIRECT_RESP2: /* Optional per 7.5.1 */
> > > case FFA_CONSOLE_LOG: /* Optional per 13.1: not in Table 13.1 */
> > > case FFA_PARTITION_INFO_GET_REGS: /* Optional for virtual instances per 13.1 */
> > > @@ -862,6 +861,22 @@ static void do_ffa_part_get(struct arm_smccc_1_2_regs *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, endp, ctxt, 1);
> > > +
> > > + struct arm_smccc_1_2_regs *args = (void *)&ctxt->regs.regs[0];
> > > +
> > > + if (FIELD_GET(FFA_SRC_ENDPOINT_MASK, endp) != vm_handle) {
> > > + ffa_to_smccc_error(regs, FFA_RET_INVALID_PARAMETERS);
> > > + return;
> > > + }
> >
> > Why do we care about checking the src id? We don't check that for
> > FFA_MSG_SEND_DIRECT_REQ and I don't think we need to care about it here
> > either.
> FFA_MSG_SEND_DIRECT_REQ is handled by do_ffa_direct_msg [0] (in the android
> common kernels, I'm not aware of efforts to upstream this).
>
> I patterned the check in do_ffa_direct_msg2 off the checking done in
> do_ffa_direct_msg. I pressume your reasoning is that this check can
> never fail since we pass in HOST_FFA_ID in kvm_host_ffa_handler. My
> thinking was that we do need to validate the source ID once we start
> using this function for requests that come from a guest VM. I could
> of course add the check in an android-specific patch, WDYT is best?
As long as upstream only has one ID for the whole of non-secure, I don't
think it makes sense to check it. So either we drop this patch or teach
upstream about different IDs, which is probably a separate series.
What I want to avoid is upstream becoming a frankenkernel comprised of
random parts of Android that don't make sense in isolation.
Will
On Fri, Jul 18, 2025 at 6:53 AM Will Deacon <will@kernel.org> wrote:
>
> On Tue, Jul 01, 2025 at 10:06:38PM +0000, Per Larsen via B4 Relay wrote:
> > 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 | 24 +++++++++++++++++++++++-
> > include/linux/arm_ffa.h | 2 ++
> > 2 files changed, 25 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
> > index 79d834120a3f3d26e17e9170c60012b60c6f5a5e..21225988a9365219ccfd69e8e599d7403b5cdf05 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/ffa.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
> > @@ -679,7 +679,6 @@ static bool ffa_call_supported(u64 func_id)
> > case FFA_NOTIFICATION_GET:
> > case FFA_NOTIFICATION_INFO_GET:
> > /* Optional interfaces added in FF-A 1.2 */
> > - case FFA_MSG_SEND_DIRECT_REQ2: /* Optional per 7.5.1 */
>
> I think that's the only change needed. In fact, maybe just don't add it
> in the earlier patch?
>
> > case FFA_MSG_SEND_DIRECT_RESP2: /* Optional per 7.5.1 */
> > case FFA_CONSOLE_LOG: /* Optional per 13.1: not in Table 13.1 */
> > case FFA_PARTITION_INFO_GET_REGS: /* Optional for virtual instances per 13.1 */
> > @@ -862,6 +861,22 @@ static void do_ffa_part_get(struct arm_smccc_1_2_regs *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, endp, ctxt, 1);
> > +
> > + struct arm_smccc_1_2_regs *args = (void *)&ctxt->regs.regs[0];
> > +
> > + if (FIELD_GET(FFA_SRC_ENDPOINT_MASK, endp) != vm_handle) {
> > + ffa_to_smccc_error(regs, FFA_RET_INVALID_PARAMETERS);
> > + return;
> > + }
>
> Why do we care about checking the src id? We don't check that for
> FFA_MSG_SEND_DIRECT_REQ and I don't think we need to care about it here
> either.
>
> Will
I think not checking the src id for FFA_MSG_SEND_DIRECT_REQ is a bug
that should be fixed as well. The receiver expects the hypervisor to
have validated this. If the src id is not validated here then the host
can impersonate other VMs or even the hypervisor itself. This bug
might be minor at the moment since other VMs can't send messages at
the moment, but it is still a bug that needs to be fixed at some
point.
--
Arve Hjønnevåg
© 2016 - 2025 Red Hat, Inc.