From nobody Tue Aug 25 14:45:31 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1776433323; cv=none; d=zohomail.com; s=zohoarc; b=N7BpZ5n83xLdcRhe6zhZNddEGgBreg7ANnj0fKutGHCTAlx/hAXuT8J+IQl42AS3YMaU9GVgtdX8YL6s0l68105jd3kyJkvrPc9rG4Z7DoGfKWM7ixIeIN4i7qnTe/uOf3AQM8IB5jF2QnppsPwVckfgfZMdgATdxS7/zhuhTok= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1776433323; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=7PmRYQ+jHBnQrx3V+V74CZkqeePfDdjRcaxt92t68DQ=; b=ZQyd+q4X7zJkjY0/0eoby40C3hnPub7BCOo4uGg+4RQS2k7JlXaAp74wYVYwj1PMQU6qYn+/Yq6dolCKKBCTUUOq45WMx/qmLl0bXBBayW2Ph2z1hDTHTMtMDUXF8AvU5R0Z29RISrb+9Bg3jFZCTaASF8youo4zCu6i5gN0JF8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1776433323661536.3407906823688; Fri, 17 Apr 2026 06:42:03 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1284307.1566158 (Exim 4.92) (envelope-from ) id 1wDjRz-0006ZC-I0; Fri, 17 Apr 2026 13:41:39 +0000 Received: by outflank-mailman (output) from mailman id 1284307.1566158; Fri, 17 Apr 2026 13:41:39 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wDjRz-0006Yt-DK; Fri, 17 Apr 2026 13:41:39 +0000 Received: by outflank-mailman (input) for mailman id 1284307; Fri, 17 Apr 2026 13:41:37 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wDjRx-0006Hl-97 for xen-devel@lists.xenproject.org; Fri, 17 Apr 2026 13:41:37 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wDjRw-009kb3-MC for xen-devel@lists.xenproject.org; Fri, 17 Apr 2026 15:41:36 +0200 Received: from [10.42.69.12] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 69e23890-e002-0a2a0a5209dd-0a2a450ce252-2 for ; Fri, 17 Apr 2026 15:41:36 +0200 Received: from [217.140.110.172] (helo=foss.arm.com) by tlsNG-d25034.mxtls.expurgate.net with ESMTP (eXpurgate 4.56.1) (envelope-from ) id 69e2388f-62f1-0a2a450c0019-d98c6eacc2d0-1 for ; Fri, 17 Apr 2026 15:41:36 +0200 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id BE7E3152B; Fri, 17 Apr 2026 06:41:29 -0700 (PDT) Received: from C3HXLD123V.arm.com (unknown [10.57.89.170]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 23F323F7D8; Fri, 17 Apr 2026 06:41:33 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=foss header.d=arm.com header.i="@arm.com" header.h="From:To:Cc:Subject:Date:In-Reply-To:References" DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1776433295; bh=K0L3j6rOuFbocNT0G1KNMjoLTTA4P4wveYKXWHNkbsg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=B/bQ7sOWm1dxec2RmlYkfebzmi/bx9ZcepiAYslRbJWBW4zioVi1baQfMBdZdGO9e iOsX8RZScJAHJVd/WiJyZMZhoIsRS3//jupKt4dEtgK+DTvoPK9HMnh1zAV9Ezl8AA M3k7OdCTx034h/uFsaB+kER/aYVcEChWw2C1lEcU= From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Jens Wiklander , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 5/6] xen/arm: ffa: Track VM notification bindings locally Date: Fri, 17 Apr 2026 15:40:53 +0200 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-d25034/1776433296-F620CCF5-86443AD2/0/0 X-purgate-type: clean X-purgate-size: 7406 X-ZohoMail-DKIM: pass (identity @arm.com) X-ZM-MESSAGEID: 1776433325533158500 Content-Type: text/plain; charset="utf-8" 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 --- 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, u= int16_t caller_id, return FFA_RET_OK; } =20 +static int32_t ffa_notif_update_vm_binding(struct ffa_ctx *ctx, + uint16_t dest_id, uint64_t bitm= ap, + bool bind) +{ + unsigned int id; + int32_t ret =3D FFA_RET_OK; + + spin_lock(&ctx->notif.notif_lock); + + for ( id =3D 0; id < FFA_NUM_VM_NOTIF; id++ ) + { + if ( !(bitmap & BIT(id, ULL)) ) + continue; + + if ( ctx->notif.vm_pending & BIT(id, ULL) ) + { + ret =3D FFA_RET_DENIED; + goto out_unlock; + } + + if ( bind ) + { + if ( ctx->notif.vm_bind[id] !=3D 0 && + ctx->notif.vm_bind[id] !=3D dest_id ) + { + ret =3D FFA_RET_DENIED; + goto out_unlock; + } + } + else if ( ctx->notif.vm_bind[id] !=3D dest_id ) + { + ret =3D FFA_RET_DENIED; + goto out_unlock; + } + } + + for ( id =3D 0; id < FFA_NUM_VM_NOTIF; id++ ) + { + if ( bitmap & BIT(id, ULL) ) + ctx->notif.vm_bind[id] =3D 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 =3D current->domain; @@ -76,11 +124,21 @@ int32_t ffa_handle_notification_bind(struct cpu_user_r= egs *regs) if ( ret ) return ret; =20 - 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); =20 - 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) | bitma= p_lo, + true); } =20 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; =20 - 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); =20 - 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) | bitma= p_lo, + false); } =20 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) =20 if ( IS_ENABLED(CONFIG_FFA_VM_TO_VM) ) { - notif_pending |=3D test_and_clear_bool(ctx->notif.vm_pending); - spin_lock(&ctx->notif.notif_lock); + if ( ctx->notif.vm_pending ) + notif_pending =3D true; + if ( ctx->notif.hyp_pending ) notif_pending =3D 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 =3D d->arch.tee; + unsigned int i; int32_t res; =20 spin_lock_init(&ctx->notif.notif_lock); ctx->notif.secure_pending =3D false; + ctx->notif.vm_pending =3D 0; + for ( i =3D 0; i < FFA_NUM_VM_NOTIF; i++ ) + ctx->notif.vm_bind[i] =3D 0; ctx->notif.hyp_pending =3D 0; =20 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 =3D d->arch.tee; + unsigned int i; =20 spin_lock(&ctx->notif.notif_lock); ctx->notif.secure_pending =3D false; + ctx->notif.vm_pending =3D 0; + for ( i =3D 0; i < FFA_NUM_VM_NOTIF; i++ ) + ctx->notif.vm_bind[i] =3D 0; ctx->notif.hyp_pending =3D 0; spin_unlock(&ctx->notif.notif_lock); =20 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 =20 #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 <=3D 64" +#endif =20 /* Feature IDs used with FFA_FEATURES */ #define FFA_FEATURE_NOTIF_PEND_INTR 0x1U @@ -334,10 +339,14 @@ struct ffa_ctx_notif { bool secure_pending; =20 /* - * True if domain is reported by FFA_NOTIFICATION_INFO_GET to have - * pending notifications from VMs (including framework ones). + * Bitmap of pending notifications from VMs (including framework ones). + */ + uint64_t vm_pending; + + /* + * Source endpoint bound to each VM notification ID (0 means unbound). */ - bool vm_pending; + uint16_t vm_bind[FFA_NUM_VM_NOTIF]; =20 /* * Lock protecting the hypervisor-managed notification state. --=20 2.53.0