[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2 5/5] xen/arm: ffa: Enable VM to VM without firmware


  • To: Jens Wiklander <jens.wiklander@xxxxxxxxxx>
  • From: Bertrand Marquis <Bertrand.Marquis@xxxxxxx>
  • Date: Fri, 21 Mar 2025 14:10:33 +0000
  • Accept-language: en-GB, en-US
  • Arc-authentication-results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 63.35.35.123) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=pass (signature was verified) header.d=arm.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dkim=[1,1,header.d=arm.com] dmarc=[1,1,header.from=arm.com])
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none
  • Arc-message-signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=oF2ux00rlnmLE5mWvYw/tbw7rOF3AScU/yhrKyfeNp0=; b=Ew3P7wXA92Yf4ZhLHuvP2/XiaVJ6ol7ketwkmaes40dn+Q/ajgvckDsSebw0T3BB/z+6FXanA/sLzuIGh118U1HbhFc+4Bx2nRaU3VIAlQ6/GXC2sX9Ft1MkIKLuTUMpwrN9Oko4S25tnXBGUGnZG9pA02cC+qRhy8PzR7DVPLSl0ArKwK9npo84ih3XH9vVGU9bDps/XWZVw3g7Jpok//eLnycZ69PCFgGf0UryR68WFkb5KIsxUzbIyMInxOVo2KbbcSbx4PVykU5psMoNT0n0pI1XNL+x/YZICzNDynTqKa04AFDGajUAwtj9V5RMbaTilJ9jLaAooVjAvqsCAg==
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=oF2ux00rlnmLE5mWvYw/tbw7rOF3AScU/yhrKyfeNp0=; b=IJAAgyYoP1mF6E3kQYWG137oHX+39EWMGD1Xnvh94F3qK4jlOotA/dDHfRtPll9Kb4UZ10awn1uiYvkrbWYi2JfM0k0+U3YNPwClD4aPsk18Jv5QTNj2Eh9r5g8nxVqs2jhWT1AA4jaGp0w9BfPKvYaDEuXDVuwV4AY7m0k6v+c5tuoBvtciqSVXpqiw7ydCfMM2mtP1cwspZ8K16nBnqDQmB6BVgsporJlK1zw8ScGQc6gX7RNLye1/JVXx+yDPa1UtIP4fiEJFB7KaoECXoUefSfK71PCJc6PrF8CnI55OZ5rsAYbSxYck+m2FotoeZTA2Ac3yqsM+6ZdfXNl6UQ==
  • Arc-seal: i=2; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=pass; b=X3r8Vz9yyTud7AslPzrmf7oNx6cdocW8dcUjNkPiW70pE6mMN29F0++fMQVzHFZ5qhDOqZrnYDb+hqoo8TpBCi2+JksOElNXe6R2KulNFQZafRJT86WCDWTrO8cq2XDmLJ/v31mRVCXlGu/3Uq57pfybgyB2GV8Ye3VMWCa9Dk/ImU+NXgEfB142Xm7Lj/7c/+b0YKmJxF3wxTLuNzSVwDjCj2dGFBHC9V1O1YfYqDgDtnag0BZEjZGpZlrLkYG/uEXylzxBMUlaX8YPcUabHkofFOJpN2NYVR0bBfmDN9+AoS0Ab6gKbzWDEvscj6ndvE8FeN4ryXYuJ4CIV6HvVw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=gzjd9V82YeZcEdzJ/R4XhiCAt/2fZhRKVSkkFscLp4U1GCXd9BxiPajTLXdNsokhZ5r3U6rAA5PhSQ6AQWLJGG8rndMuJBz+SGbl04al/b+fK8AjCDo0PmJP7jJKBGp14c5+HUFaz77caLfgwiPySKeZKtASFpWwTJ3TDn0Kw4f8Tgrfp7mfkAdKiU9xpuGGwb03Ei5BpN/emdfyZs3nhXdlNql/uwnZA2+Q8hX5ebnJOSff3DryKf8po0fh6FSjQaeIA7d5HXLMjdWrzTYxezi6+4ZDwZXkccOpWQ2lyroPHSagMzSutsUYUKp8SvBT7fBX53NQ1NB1CxgJvAF3Og==
  • Authentication-results-original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com;
  • Cc: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Volodymyr Babchuk <volodymyr_babchuk@xxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>
  • Delivery-date: Fri, 21 Mar 2025 14:10:58 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Nodisclaimer: true
  • Original-authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com;
  • Thread-index: AQHbkcvqUcfBAkFPRke6B/ThQimwz7N9WnkAgAAIEICAAAx4gIAAPN+AgAADowCAAALegA==
  • Thread-topic: [PATCH v2 5/5] xen/arm: ffa: Enable VM to VM without firmware

Hi Jens,

> On 21 Mar 2025, at 15:00, Jens Wiklander <jens.wiklander@xxxxxxxxxx> wrote:
> 
> Hi Bertrand,
> 
> On Fri, Mar 21, 2025 at 2:47 PM Bertrand Marquis
> <Bertrand.Marquis@xxxxxxx> wrote:
>> 
>> Hi Jens,
>> 
>>> On 21 Mar 2025, at 11:09, Jens Wiklander <jens.wiklander@xxxxxxxxxx> wrote:
>>> 
>>> Hi,
>>> 
>>> On Fri, Mar 21, 2025 at 10:25 AM Bertrand Marquis
>>> <Bertrand.Marquis@xxxxxxx> wrote:
>>>> 
>>>> Hi Jens,
>>>> 
>>>>> On 21 Mar 2025, at 09:55, Jens Wiklander <jens.wiklander@xxxxxxxxxx> 
>>>>> wrote:
>>>>> 
>>>>> Hi Bertrand,
>>>>> 
>>>>> On Mon, Mar 10, 2025 at 3:51 PM Bertrand Marquis
>>>>> <bertrand.marquis@xxxxxxx> wrote:
>>>>>> 
>>>>>> When VM to VM support is activated and there is no suitable FF-A support
>>>>>> in the firmware, enable FF-A support for VMs to allow using it for VM to
>>>>>> VM communications.
>>>>>> If there is Optee running in the secure world and using the non FF-A
>>>>> 
>>>>> It's spelled OP-TEE in text, and optee or OPTEE in identifiers.
>>>> 
>>>> ack
>>>> 
>>>>> 
>>>>>> communication system, having CONFIG_FFA_VM_TO_VM could be non functional
>>>>>> (if optee is probed first) or Optee could be non functional (if FF-A is
>>>>>> probed first) so it is not recommended to activate the configuration
>>>>>> option for such systems.
>>>>>> 
>>>>>> To make buffer full notification work between VMs when there is not
>>>>> 
>>>>> s/not/no/
>>>> 
>>>> ack
>>>> 
>>>>> 
>>>>>> firmware, rework the notification handling and modify the global flag to
>>>>>> only be used as check for firmware notification support instead.
>>>>>> 
>>>>>> Modify part_info_get to return the list of VMs when there is no firmware
>>>>>> support.
>>>>>> 
>>>>>> Signed-off-by: Bertrand Marquis <bertrand.marquis@xxxxxxx>
>>>>>> ---
>>>>>> Changes in v2:
>>>>>> - replace ifdef with IS_ENABLED when possible
>>>>>> ---
>>>>>> xen/arch/arm/tee/ffa.c          |  12 +++-
>>>>>> xen/arch/arm/tee/ffa_notif.c    | 114 ++++++++++++++++----------------
>>>>>> xen/arch/arm/tee/ffa_partinfo.c |   3 +-
>>>>>> 3 files changed, 69 insertions(+), 60 deletions(-)
>>>>>> 
>>>>>> diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c
>>>>>> index 3bbdd7168a6b..f6582d2e855a 100644
>>>>>> --- a/xen/arch/arm/tee/ffa.c
>>>>>> +++ b/xen/arch/arm/tee/ffa.c
>>>>>> @@ -324,8 +324,9 @@ static int ffa_domain_init(struct domain *d)
>>>>>>   struct ffa_ctx *ctx;
>>>>>>   int ret;
>>>>>> 
>>>>>> -    if ( !ffa_fw_version )
>>>>>> +    if ( !IS_ENABLED(CONFIG_FFA_VM_TO_VM) && !ffa_fw_version )
>>>>>>       return -ENODEV;
>>>>>> +
>>>>>>   /*
>>>>>>    * We are using the domain_id + 1 as the FF-A ID for VMs as FF-A ID 0 
>>>>>> is
>>>>>>    * reserved for the hypervisor and we only support secure endpoints 
>>>>>> using
>>>>>> @@ -549,6 +550,15 @@ err_no_fw:
>>>>>>   bitmap_zero(ffa_fw_abi_supported, FFA_ABI_BITMAP_SIZE);
>>>>>>   printk(XENLOG_WARNING "ARM FF-A No firmware support\n");
>>>>>> 
>>>>>> +    if ( IS_ENABLED(CONFIG_FFA_VM_TO_VM) )
>>>>>> +    {
>>>>>> +        INIT_LIST_HEAD(&ffa_teardown_head);
>>>>>> +        init_timer(&ffa_teardown_timer, ffa_teardown_timer_callback, 
>>>>>> NULL, 0);
>>>>>> +
>>>>>> +        printk(XENLOG_INFO "ARM FF-A only available between VMs\n");
>>>>>> +        return true;
>>>>>> +    }
>>>>>> +
>>>>>>   return false;
>>>>>> }
>>>>>> 
>>>>>> diff --git a/xen/arch/arm/tee/ffa_notif.c b/xen/arch/arm/tee/ffa_notif.c
>>>>>> index d19aa5c5bef6..0673e53a9def 100644
>>>>>> --- a/xen/arch/arm/tee/ffa_notif.c
>>>>>> +++ b/xen/arch/arm/tee/ffa_notif.c
>>>>>> @@ -16,7 +16,7 @@
>>>>>> 
>>>>>> #include "ffa_private.h"
>>>>>> 
>>>>>> -static bool __ro_after_init notif_enabled;
>>>>>> +static bool __ro_after_init fw_notif_enabled;
>>>>>> static unsigned int __ro_after_init notif_sri_irq;
>>>>>> 
>>>>>> int ffa_handle_notification_bind(struct cpu_user_regs *regs)
>>>>>> @@ -27,21 +27,17 @@ int ffa_handle_notification_bind(struct 
>>>>>> cpu_user_regs *regs)
>>>>>>   uint32_t bitmap_lo = get_user_reg(regs, 3);
>>>>>>   uint32_t bitmap_hi = get_user_reg(regs, 4);
>>>>>> 
>>>>>> -    if ( !notif_enabled )
>>>>>> -        return FFA_RET_NOT_SUPPORTED;
>>>>>> -
>>>>>>   if ( (src_dst & 0xFFFFU) != ffa_get_vm_id(d) )
>>>>>>       return FFA_RET_INVALID_PARAMETERS;
>>>>>> 
>>>>>>   if ( flags )    /* Only global notifications are supported */
>>>>>>       return FFA_RET_DENIED;
>>>>>> 
>>>>>> -    /*
>>>>>> -     * We only support notifications from SP so no need to check the 
>>>>>> sender
>>>>>> -     * endpoint ID, the SPMC will take care of that for us.
>>>>>> -     */
>>>>>> -    return ffa_simple_call(FFA_NOTIFICATION_BIND, src_dst, flags, 
>>>>>> bitmap_lo,
>>>>>> -                           bitmap_hi);
>>>>>> +    if ( FFA_ID_IS_SECURE(src_dst>>16) && fw_notif_enabled )
>>>>> 
>>>>> Please add space before and after '>>', here and in the function below
>>>>> in this patch.
>>>> 
>>>> ack
>>>> 
>>>>> 
>>>>>> +        return ffa_simple_call(FFA_NOTIFICATION_BIND, src_dst, flags,
>>>>>> +                               bitmap_lo, bitmap_hi);
>>>>>> +
>>>>>> +    return FFA_RET_NOT_SUPPORTED;
>>>>>> }
>>>>>> 
>>>>>> int ffa_handle_notification_unbind(struct cpu_user_regs *regs)
>>>>>> @@ -51,32 +47,34 @@ int ffa_handle_notification_unbind(struct 
>>>>>> cpu_user_regs *regs)
>>>>>>   uint32_t bitmap_lo = get_user_reg(regs, 3);
>>>>>>   uint32_t bitmap_hi = get_user_reg(regs, 4);
>>>>>> 
>>>>>> -    if ( !notif_enabled )
>>>>>> -        return FFA_RET_NOT_SUPPORTED;
>>>>>> -
>>>>>>   if ( (src_dst & 0xFFFFU) != ffa_get_vm_id(d) )
>>>>>>       return FFA_RET_INVALID_PARAMETERS;
>>>>>> 
>>>>>> -    /*
>>>>>> -     * We only support notifications from SP so no need to check the
>>>>>> -     * destination endpoint ID, the SPMC will take care of that for us.
>>>>>> -     */
>>>>>> -    return  ffa_simple_call(FFA_NOTIFICATION_UNBIND, src_dst, 0, 
>>>>>> bitmap_lo,
>>>>>> -                            bitmap_hi);
>>>>>> +    if ( FFA_ID_IS_SECURE(src_dst>>16) && fw_notif_enabled )
>>>>>> +        return  ffa_simple_call(FFA_NOTIFICATION_UNBIND, src_dst, 0, 
>>>>>> bitmap_lo,
>>>>>> +                                bitmap_hi);
>>>>>> +
>>>>>> +    return FFA_RET_NOT_SUPPORTED;
>>>>>> }
>>>>>> 
>>>>>> void ffa_handle_notification_info_get(struct cpu_user_regs *regs)
>>>>>> {
>>>>>>   struct domain *d = current->domain;
>>>>>>   struct ffa_ctx *ctx = d->arch.tee;
>>>>>> +    bool notif_pending = false;
>>>>>> 
>>>>>> -    if ( !notif_enabled )
>>>>>> +    if ( !IS_ENABLED(CONFIG_FFA_VM_TO_VM) && !fw_notif_enabled )
>>>>>>   {
>>>>>>       ffa_set_regs_error(regs, FFA_RET_NOT_SUPPORTED);
>>>>>>       return;
>>>>>>   }
>>>>>> 
>>>>>> -    if ( test_and_clear_bool(ctx->notif.secure_pending) )
>>>>>> +    notif_pending = ctx->notif.secure_pending;
>>>>>> +#ifdef CONFIG_FFA_VM_TO_VM
>>>>>> +    notif_pending |= ctx->notif.buff_full_pending;
>>>>>> +#endif
>>>>> 
>>>>> Shouldn't ctx->notif.secure_pending and ctx->notif.secure_pending be
>>>>> cleared also, like:
>>>>> notif_pending = test_and_clear_bool(ctx->notif.secure_pending) ||
>>>>>              test_and_clear_bool(ctx->notif.buff_full_pending);
>>>> 
>>>> Notification info get is returning who has pending notification but only
>>>> notification get should erase pending notifications.
>>> 
>>> FFA_NOTIFICATION_INFO_GET can return a "More pending notifications
>>> flag" in w2/x2 to inform the caller that it should call
>>> FFA_NOTIFICATION_INFO_GET again to get the remaining receiver
>>> endpoints. How can the ABI know where to resume the next time if the
>>> previous pending receivers aren't cleared?
>> 
>> I just checked the specification and you are right.
>> It is explicitly saying that "Information about pending notifications is
>> returned only once".
>> 
>>> 
>>> The more pending notifications flag will not be needed here as we're
>>> dealing with a single endpoint at a time so it might be more of a
>>> philosophical question. I don't think it causes problems for the guest
>>> to keep secure_pending unchanged for FFA_NOTIFICATION_INFO_GET, but we
>>> should mention the changed behaviour in the commit message.
>>> 
>> 
>> I agree I should discard the secure_pending flag in the implementation but
>> I need to find a solution for the buffer full notification as I still need 
>> to signal
>> it in notification get even if notification info get was called.
>> 
>> I will do the following:
>> - change secure_pending into pending_notif.
>> - set pending_notif when current secure_pending is set
>> - set pending_notif and buff_full_pending on indirect message
>> - clean pending_notif in notif_info_get
>> - clean pending_notif and buff_full in notif_get
>> 
>> Do you agree this is the right path ?
> 
> Yes, this is the way. :-)

Well in fact there is a mistake in this way and I had to do something
a bit different.

When we have a notification get, we can only clear secure_pending
if FFA_NOTIF_FLAG_BITMAP_SP(M) are passed.

So i think i have to do the following:
- secure_pending: set and clean as they are now
- vm_pending: set when raising buf full and clean in info_get or get
  with FFA_NOTIF_FLAG_BITMAP_HYP set
- buff_full_pending only cleaned in get with 
  FFA_NOTIF_FLAG_BITMAP_HYP set

This way info_get would still return something if a get is done but with
only flags to retrieve secure and there is a buff full notif pending or with
only HYP and secure ones pending.

Giving something like that:

--- a/xen/arch/arm/tee/ffa_notif.c
+++ b/xen/arch/arm/tee/ffa_notif.c
@@ -69,6 +69,7 @@ void ffa_handle_notification_info_get(struct cpu_user_regs 
*regs)
 {
     struct domain *d = current->domain;
     struct ffa_ctx *ctx = d->arch.tee;
+    bool notif_pending;

     if ( !notif_enabled )
     {
@@ -76,7 +77,11 @@ void ffa_handle_notification_info_get(struct cpu_user_regs 
*regs)
         return;
     }

-    if ( test_and_clear_bool(ctx->notif.secure_pending) )
+    notif_pending = test_and_clear_bool(ctx->notif.secure_pending);
+    if ( IS_ENABLED(CONFIG_FFA_VM_TO_VM) )
+        notif_pending |= test_and_clear_bool(ctx->notif.vm_pending)
+
+    if ( notif_pending )
     {
         /* A pending global notification for the guest */
         ffa_set_regs(regs, FFA_SUCCESS_64, 0,
@@ -153,11 +158,13 @@ void ffa_handle_notification_get(struct cpu_user_regs 
*regs)
             w6 = resp.a6;
     }

-#ifdef CONFIG_FFA_VM_TO_VM
-    if ( flags & FFA_NOTIF_FLAG_BITMAP_HYP &&
+    if ( IS_ENABLED(CONFIG_FFA_VM_TO_VM) &&
+          flags & FFA_NOTIF_FLAG_BITMAP_HYP &&
           test_and_clear_bool(ctx->notif.buff_full_pending) )
+    {
+        ACCESS_ONCE(ctx->notif.vm_pending) = false;
         w7 = FFA_NOTIF_RX_BUFFER_FULL;
-#endif
+    }

     ffa_set_regs(regs, FFA_SUCCESS_32, 0, w2, w3, w4, w5, w6, w7);
 }
@@ -189,7 +196,8 @@ void ffa_raise_rx_buffer_full(struct domain *d)
     if ( !ctx )
         return;

-    if ( !test_and_set_bool(ctx->notif.buff_full_pending) )
+    ACCESS_ONCE(ctx->notif.buff_full_pending) = true
+    if ( !test_and_set_bool(ctx->notif.vm_pending) )
         vgic_inject_irq(d, d->vcpu[0], notif_sri_irq, true);
 }

Cheers
Bertrand


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.