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

Re: [PATCH 5/6] xen/arm: ffa: Track VM notification bindings locally


  • To: Jens Wiklander <jens.wiklander@xxxxxxxxxx>
  • From: Bertrand Marquis <Bertrand.Marquis@xxxxxxx>
  • Date: Thu, 23 Apr 2026 07:44:12 +0000
  • Accept-language: en-GB, en-US
  • Arc-authentication-results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 4.158.2.129) smtp.rcpttodomain=linaro.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=4fVyrfeACI5cUP5mPal2D/GFOoj38PCJBF36dY0hRdg=; b=TkObDwUcDZhQHXPvSkAiBtsYmzPjoG+X/+Dmbpli13SlcwkbqKF0+zNGiUIPvZua8X7hI/Q5DLnm5d6tEmOAmzm2PiNYyxuVZof8RAqfq4IRAwOyY7fgaS3JSeKiidIOR9CcQpwY9Jn1zgjO9G5HbAxIqhVfz9EoJVYlgQq/yawq7X8H2+Tqj4D1wduhRnwBv7/BxIYzyO/7bxoeCNkDgQ8s5KjikTL8L4/Gx/3d9GuWk8iZocR36eF2cLgfBerQ5LWeGK7Z64dn0kpSgV3ycEVPYGDXNfy4Zg6AFQfdo719CT4hpCqKDOFRXoN77z4I5vFkMvfnOS88Ttj56xSQDw==
  • 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=4fVyrfeACI5cUP5mPal2D/GFOoj38PCJBF36dY0hRdg=; b=EAJlAQEq7mGrwUG9NzgcsfaujKn76sSN7kojt6PkGjKOPtyggeiYDO/YnyF/pFA6v4Hf6fvX4PzaaWyIUkfm1llJN4yhGr+ITng4EQ4haBXWCb07Tj/Czrj96ZBD7/f+gu+zIrDhCX6xb8WJl2BIMSRHanWPkx42xb59kKpN0KwjahRieOSA/icVQWXuf1QA/f+k1puDSbLSpUzEq3qtz5ML60DK2NETDqL3/IRq0NnspBOoXKVwUJtw8/Ksz6hPv4kQXLGjGJqdFUebGB+wNCEj97729h+cWwu7utem9aY+tyRZ2Ra0lDfcztPLWyme4tEoIvuiB3NRCXQ0hkgXHA==
  • Arc-seal: i=2; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=pass; b=v+EEsAE8EvI0QaTmJeGnAitilw7IUNk8FvGJgxCV/4NWHJgkoKejOEFx85Ba+m8ZnKT7Kbh7b7dcdcZb+R9dXKROQTxwCIueFcPyY9udKPH2Avh5fTuzNlDV3mmmRJh0AzGyx08l2mu/HAxyL2XDY2jifwqlDE63Ot4pPFEu/OJI9emw+cPgA/vWM+4/IqfQyly5rm8X3aN3bWjxegG/RlBDMpc0rX5jxbJsmqcJEuSKqHnx6dh1ldx0Evqc+dHU6aXzxvzfoaO0fSCU+IBfARbmiooZAu2TMgj0kKOv1EUiZci9NEMdHSRYoOe4r6C4jRA1JW/1eOb7CpUtXJWRbA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=f+zyj5hbQNkaOBzZ7R8p1r8L24jQCE8agEjMOOTtJMBiLFNeRFFlNzsMN4VE/bVHQcKuNZsS1nXRegRvC2xjSfWDLr58oAqA+ZdX92MQ5jtb8myFl03kUQRWIBEUo6JHaU0V/GYSdRBo3pc8JC5iY3n0m/4COWSbV6H8EGzYgts8mSvcgWzU4Ip6vkHNS9a+LTkL5q/6j9Jl/EBA2VdpFYN2yhDX9IqgZMdOXW7xx6trj++ipbPcKljp0UO+Mn7Riu192VkKqK5hkd2OXOdoSpiuvc04CdZY8bILyNkFuLwdzjJuiylleURLRcElPQrBRTr/Fo9vnQq+msjp6ALpGw==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=arm.com header.i="@arm.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"; dkim=pass header.s=selector1 header.d=arm.com header.i="@arm.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • 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: Thu, 23 Apr 2026 07:45:33 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Nodisclaimer: true
  • Thread-index: AQHcznArOQx42qP1+k2R4bBbbIb5Y7XrGR0AgAEz6AA=
  • Thread-topic: [PATCH 5/6] xen/arm: ffa: Track VM notification bindings locally

Hi Jens,

> On 22 Apr 2026, at 15:21, Jens Wiklander <jens.wiklander@xxxxxxxxxx> wrote:
> 
> Hi Bertrand,
> 
> On Fri, Apr 17, 2026 at 3:41 PM Bertrand Marquis
> <bertrand.marquis@xxxxxxx> wrote:
>> 
>> VM-to-VM notifications need receiver-side bind state so Xen can validate
>> which sender owns each notification bit. Non-secure BIND and UNBIND
>> requests currently have no local state and cannot enforce that contract.
>> 
>> Add per-bit VM notification binding state to struct ffa_ctx_notif and
>> use it to handle non-secure BIND and UNBIND requests when
>> CONFIG_FFA_VM_TO_VM is enabled. The update helper validates the whole
>> request under notif_lock before mutating anything, denies bind or
>> unbind when a bit is pending, rejects rebinding to a different sender,
>> and keeps rebinding to the same sender idempotent.
>> 
>> Promote vm_pending to a bitmap so the bind logic can reason per
>> notification ID, use that bitmap directly when reporting pending state,
>> and initialize and clear the new VM notification state during domain
>> init and teardown.
>> 
>> Functional impact: when CONFIG_FFA_VM_TO_VM is enabled, Xen tracks VM
>> notification bindings locally and validates non-secure bind and unbind
>> requests against that state.
>> 
>> Signed-off-by: Bertrand Marquis <bertrand.marquis@xxxxxxx>
>> ---
>> xen/arch/arm/tee/ffa_notif.c   | 97 ++++++++++++++++++++++++++++++----
>> xen/arch/arm/tee/ffa_private.h | 15 ++++--
>> 2 files changed, 99 insertions(+), 13 deletions(-)
>> 
>> diff --git a/xen/arch/arm/tee/ffa_notif.c b/xen/arch/arm/tee/ffa_notif.c
>> index fff00ca2baec..4def701f0130 100644
>> --- a/xen/arch/arm/tee/ffa_notif.c
>> +++ b/xen/arch/arm/tee/ffa_notif.c
>> @@ -56,6 +56,54 @@ static int32_t ffa_notif_parse_params(uint16_t dom_id, 
>> uint16_t caller_id,
>>     return FFA_RET_OK;
>> }
>> 
>> +static int32_t ffa_notif_update_vm_binding(struct ffa_ctx *ctx,
>> +                                           uint16_t dest_id, uint64_t 
>> bitmap,
>> +                                           bool bind)
>> +{
>> +    unsigned int id;
>> +    int32_t ret = FFA_RET_OK;
>> +
>> +    spin_lock(&ctx->notif.notif_lock);
>> +
>> +    for ( id = 0; id < FFA_NUM_VM_NOTIF; id++ )
>> +    {
>> +        if ( !(bitmap & BIT(id, ULL)) )
>> +            continue;
>> +
>> +        if ( ctx->notif.vm_pending & BIT(id, ULL) )
>> +        {
>> +            ret = FFA_RET_DENIED;
>> +            goto out_unlock;
>> +        }
>> +
>> +        if ( bind )
>> +        {
>> +            if ( ctx->notif.vm_bind[id] != 0 &&
>> +                 ctx->notif.vm_bind[id] != dest_id )
>> +            {
>> +                ret = FFA_RET_DENIED;
>> +                goto out_unlock;
>> +            }
>> +        }
>> +        else if ( ctx->notif.vm_bind[id] != dest_id )
>> +        {
>> +            ret = FFA_RET_DENIED;
>> +            goto out_unlock;
>> +        }
>> +    }
>> +
>> +    for ( id = 0; id < FFA_NUM_VM_NOTIF; id++ )
>> +    {
>> +        if ( bitmap & BIT(id, ULL) )
>> +            ctx->notif.vm_bind[id] = bind ? dest_id : 0;
>> +    }
>> +
>> +out_unlock:
>> +    spin_unlock(&ctx->notif.notif_lock);
>> +
>> +    return ret;
>> +}
>> +
>> int32_t ffa_handle_notification_bind(struct cpu_user_regs *regs)
>> {
>>     struct domain *d = current->domain;
>> @@ -76,11 +124,21 @@ int32_t ffa_handle_notification_bind(struct 
>> cpu_user_regs *regs)
>>     if ( ret )
>>         return ret;
>> 
>> -    if ( FFA_ID_IS_SECURE(dest_id) && fw_notif_enabled )
>> -        return ffa_simple_call(FFA_NOTIFICATION_BIND, src_dst, flags,
>> -                               bitmap_lo, bitmap_hi);
>> +    if ( FFA_ID_IS_SECURE(dest_id) )
>> +    {
>> +        if ( fw_notif_enabled )
>> +            return ffa_simple_call(FFA_NOTIFICATION_BIND, src_dst, flags,
>> +                                   bitmap_lo, bitmap_hi);
>> 
>> -    return FFA_RET_NOT_SUPPORTED;
>> +        return FFA_RET_NOT_SUPPORTED;
>> +    }
>> +
>> +    if ( !IS_ENABLED(CONFIG_FFA_VM_TO_VM) )
>> +        return FFA_RET_NOT_SUPPORTED;
>> +
>> +    return ffa_notif_update_vm_binding(ctx, dest_id,
>> +                                       ((uint64_t)bitmap_hi << 32) | 
>> bitmap_lo,
>> +                                       true);
>> }
>> 
>> int32_t ffa_handle_notification_unbind(struct cpu_user_regs *regs)
>> @@ -99,11 +157,21 @@ int32_t ffa_handle_notification_unbind(struct 
>> cpu_user_regs *regs)
>>     if ( ret )
>>         return ret;
>> 
>> -    if ( FFA_ID_IS_SECURE(dest_id) && fw_notif_enabled )
>> -        return ffa_simple_call(FFA_NOTIFICATION_UNBIND, src_dst, 0, 
>> bitmap_lo,
>> -                               bitmap_hi);
>> +    if ( FFA_ID_IS_SECURE(dest_id) )
>> +    {
>> +        if ( fw_notif_enabled )
>> +            return ffa_simple_call(FFA_NOTIFICATION_UNBIND, src_dst, 0,
>> +                                   bitmap_lo, bitmap_hi);
>> 
>> -    return FFA_RET_NOT_SUPPORTED;
>> +        return FFA_RET_NOT_SUPPORTED;
>> +    }
>> +
>> +    if ( !IS_ENABLED(CONFIG_FFA_VM_TO_VM) )
>> +        return FFA_RET_NOT_SUPPORTED;
>> +
>> +    return ffa_notif_update_vm_binding(ctx, dest_id,
>> +                                       ((uint64_t)bitmap_hi << 32) | 
>> bitmap_lo,
>> +                                       false);
>> }
>> 
>> void ffa_handle_notification_info_get(struct cpu_user_regs *regs)
>> @@ -125,9 +193,10 @@ void ffa_handle_notification_info_get(struct 
>> cpu_user_regs *regs)
>> 
>>     if ( IS_ENABLED(CONFIG_FFA_VM_TO_VM) )
>>     {
>> -        notif_pending |= test_and_clear_bool(ctx->notif.vm_pending);
>> -
>>         spin_lock(&ctx->notif.notif_lock);
>> +        if ( ctx->notif.vm_pending )
>> +            notif_pending = true;
>> +
>>         if ( ctx->notif.hyp_pending )
>>             notif_pending = true;
>>         spin_unlock(&ctx->notif.notif_lock);
>> @@ -497,10 +566,14 @@ void ffa_notif_init(void)
>> int ffa_notif_domain_init(struct domain *d)
>> {
>>     struct ffa_ctx *ctx = d->arch.tee;
>> +    unsigned int i;
>>     int32_t res;
>> 
>>     spin_lock_init(&ctx->notif.notif_lock);
>>     ctx->notif.secure_pending = false;
>> +    ctx->notif.vm_pending = 0;
>> +    for ( i = 0; i < FFA_NUM_VM_NOTIF; i++ )
>> +        ctx->notif.vm_bind[i] = 0;
>>     ctx->notif.hyp_pending = 0;
>> 
>>     if ( fw_notif_enabled )
>> @@ -516,9 +589,13 @@ int ffa_notif_domain_init(struct domain *d)
>> void ffa_notif_domain_destroy(struct domain *d)
>> {
>>     struct ffa_ctx *ctx = d->arch.tee;
>> +    unsigned int i;
>> 
>>     spin_lock(&ctx->notif.notif_lock);
>>     ctx->notif.secure_pending = false;
>> +    ctx->notif.vm_pending = 0;
>> +    for ( i = 0; i < FFA_NUM_VM_NOTIF; i++ )
>> +        ctx->notif.vm_bind[i] = 0;
> 
> Why not memset(ctx->notif.vm_bind, 0, sizeof(ctx->notif.vm_bind)?

Definitely better to use memset, I will use it here and in domain_init
instead of an explicit loop.

> 
>>     ctx->notif.hyp_pending = 0;
>>     spin_unlock(&ctx->notif.notif_lock);
>> 
>> diff --git a/xen/arch/arm/tee/ffa_private.h b/xen/arch/arm/tee/ffa_private.h
>> index 5693772481ed..6d83afb3d00a 100644
>> --- a/xen/arch/arm/tee/ffa_private.h
>> +++ b/xen/arch/arm/tee/ffa_private.h
>> @@ -236,6 +236,11 @@
>> #define FFA_NOTIF_INFO_GET_ID_COUNT_MASK    0x1F
>> 
>> #define FFA_NOTIF_RX_BUFFER_FULL        BIT(0, U)
>> +#define FFA_NUM_VM_NOTIF                64U
>> +
>> +#if FFA_NUM_VM_NOTIF > 64
>> +#error "FFA_NUM_VM_NOTIF must be <= 64"
>> +#endif
> 
> BUILD_BUG_ON(FFA_NUM_VM_NOTIF > 64) ?

Yes that would be cleaner.
I will put it in ffa_notif_domain_init and remove that
from the header.

Cheers
Bertrand


 


Rackspace

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