From nobody Tue Sep 22 15:06:11 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=1777441490; cv=none; d=zohomail.com; s=zohoarc; b=KmOKv89wsTkB/gmlEIEjjZNngQaRGdo1FYqQQFiDMSyYUuQWA2wIxd3A+jhhXBTQ+dGnl0f0DSaTiyTRtgKAkQ43GjNnAqqs8Cjd2bffR8xUvqyEa3b4KTTHyIe+dKRzGkIpjVeszCxdG0EwbyIrciLgVMJPZVS4WlDAJPbE+Hc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777441490; 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=HZrwRA5VNHqj01+MxnvaenWghzavARtkdTgaFx5fOZc=; b=oBzto7ghC97g+u/spstlUHKFyLLyK9d1fHTN09MB3RF1OUVR02hlHfTfGRmFg2UOCNJOYcuVMTiE+IT4yVnFB8fEZf8xXXErR/guNfKSfU6sxpBD+yUWCc4rKiGnRaZeENEaMA87fFgTCEimlDRgb62UmYD5BuU/mEjcnlUldoU= 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 177744149015254.35443528404005; Tue, 28 Apr 2026 22:44:50 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1296942.1573082 (Exim 4.92) (envelope-from ) id 1wHxiT-0008J8-Rw; Wed, 29 Apr 2026 05:44:09 +0000 Received: by outflank-mailman (output) from mailman id 1296942.1573082; Wed, 29 Apr 2026 05:44:09 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wHxiT-0008Iz-P6; Wed, 29 Apr 2026 05:44:09 +0000 Received: by outflank-mailman (input) for mailman id 1296942; Wed, 29 Apr 2026 05:44:08 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wHxiS-0008En-GJ for xen-devel@lists.xenproject.org; Wed, 29 Apr 2026 05:44:08 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wHxiR-0078Bd-S1 for xen-devel@lists.xenproject.org; Wed, 29 Apr 2026 07:44:07 +0200 Received: from [10.42.69.7] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 69f19a9f-5cb7-0a2a0a5109dd-0a2a4507ede2-12 for ; Wed, 29 Apr 2026 07:44:07 +0200 Received: from [217.140.110.172] (helo=foss.arm.com) by tlsNG-ef75cf.mxtls.expurgate.net with ESMTP (eXpurgate 4.56.1) (envelope-from ) id 69f19aa6-229c-0a2a45070019-d98c6eacb28e-1 for ; Wed, 29 Apr 2026 07:44:07 +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 C745D328D; Tue, 28 Apr 2026 22:44:00 -0700 (PDT) Received: from C3HXLD123V.arm.com (unknown [10.57.90.163]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id EB45A3F62B; Tue, 28 Apr 2026 22:44:04 -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=1777441446; bh=IvYNqDbera/Ke8I0F2UPOw6J8/rPOohK8qd0lYFvQZM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=inm5aBwxI6owTAxlvk6jPjRmOK55M16BCQgB5DNdQ/iBYs8C7yhJXqo06rL/wuu0w 43oOdT64yp7kACF+j41i1kQHlbRVvv4EqgZQTvdy37cPjUdw+/LfgDdi9feTyf7McC hYscRSAFQ+daJBvOFLXT3j5e/qQiKt/G4s4UbyaM= From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Jens Wiklander , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v2 2/6] xen/arm: ffa: Track hypervisor notifications in a bitmap Date: Wed, 29 Apr 2026 07:43:23 +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-ef75cf/1777441447-AD364C48-2A5E094F/0/0 X-purgate-type: clean X-purgate-size: 6808 X-ZohoMail-DKIM: pass (identity @arm.com) X-ZM-MESSAGEID: 1777441491954158500 Content-Type: text/plain; charset="utf-8" Hypervisor notifications are currently tracked with a dedicated buff_full_pending boolean. The old RX-buffer-full path also exposed a pending indication indirectly via vm_pending, so FFA_NOTIFICATION_INFO_GET could clear that summary before the guest retrieved the Hypervisor notification bitmap with FFA_NOTIFICATION_GET. Replace the single boolean with a Hypervisor notification bitmap protected by notif_lock. INFO_GET reports pending when hyp_pending is non-zero, GET returns and clears the HYP bitmap under the lock, and RX-buffer-full now keeps notif_lock held across the local NPI decision. notif_irq_raised is only set when an NPI is actually injected, and is cleared once the local pending state is consumed. Initialize and clear the bitmap during domain lifecycle handling, and use ctx->ffa_id for bitmap create and destroy so the notification state stays tied to the cached FF-A endpoint ID. If the local injection attempt fails because no vCPU is online, hyp_pending remains set and notif_irq_raised remains clear. This keeps the RX-buffer-full notification pending until the guest retrieves it, without publishing a successful local IRQ state too early. Functional impact: RX-buffer-full remains pending in hyp_pending until FFA_NOTIFICATION_GET, and failed local NPI injection no longer leaves Xen thinking the interrupt was already raised. Signed-off-by: Bertrand Marquis Reviewed-by: Jens Wiklander --- Changes since v1: - clarify that v1 exposed RX-buffer-full indirectly via vm_pending - document that v2 keeps the HYP pending indication until FFA_NOTIFICATION_GET - keep RX-buffer-full pending state stable across failed local NPI injection attempts --- xen/arch/arm/tee/ffa_notif.c | 56 ++++++++++++++++++++++++++-------- xen/arch/arm/tee/ffa_private.h | 15 +++++++-- 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/xen/arch/arm/tee/ffa_notif.c b/xen/arch/arm/tee/ffa_notif.c index 07bc5cb3a430..a631481e3815 100644 --- a/xen/arch/arm/tee/ffa_notif.c +++ b/xen/arch/arm/tee/ffa_notif.c @@ -19,7 +19,7 @@ static bool __ro_after_init fw_notif_enabled; static unsigned int __ro_after_init notif_sri_irq; =20 -static void inject_notif_pending(struct domain *d) +static bool inject_notif_pending(struct domain *d) { struct vcpu *v; =20 @@ -33,13 +33,15 @@ static void inject_notif_pending(struct domain *d) if ( is_vcpu_online(v) ) { vgic_inject_irq(d, v, GUEST_FFA_NOTIF_PEND_INTR_ID, true); - return; + return true; } } =20 if ( printk_ratelimit() ) printk(XENLOG_G_DEBUG "%pd: ffa: can't inject NPI, all vCPUs offli= ne\n", d); + + return false; } =20 int32_t ffa_handle_notification_bind(struct cpu_user_regs *regs) @@ -94,8 +96,15 @@ void ffa_handle_notification_info_get(struct cpu_user_re= gs *regs) =20 notif_pending =3D test_and_clear_bool(ctx->notif.secure_pending); if ( IS_ENABLED(CONFIG_FFA_VM_TO_VM) ) + { notif_pending |=3D test_and_clear_bool(ctx->notif.vm_pending); =20 + spin_lock(&ctx->notif.notif_lock); + if ( ctx->notif.hyp_pending ) + notif_pending =3D true; + spin_unlock(&ctx->notif.notif_lock); + } + if ( notif_pending ) { /* A pending global notification for the guest */ @@ -174,12 +183,19 @@ void ffa_handle_notification_get(struct cpu_user_regs= *regs) w6 =3D resp.a6; } =20 - if ( IS_ENABLED(CONFIG_FFA_VM_TO_VM) && - flags & FFA_NOTIF_FLAG_BITMAP_HYP && - test_and_clear_bool(ctx->notif.buff_full_pending) ) + if ( IS_ENABLED(CONFIG_FFA_VM_TO_VM) ) { - ACCESS_ONCE(ctx->notif.vm_pending) =3D false; - w7 =3D FFA_NOTIF_RX_BUFFER_FULL; + spin_lock(&ctx->notif.notif_lock); + + if ( (flags & FFA_NOTIF_FLAG_BITMAP_HYP) && ctx->notif.hyp_pending= ) + { + w7 =3D ctx->notif.hyp_pending; + ctx->notif.hyp_pending =3D 0; + if ( !ctx->notif.vm_pending ) + ctx->notif.notif_irq_raised =3D false; + } + + spin_unlock(&ctx->notif.notif_lock); } =20 ffa_set_regs(regs, FFA_SUCCESS_32, 0, w2, w3, w4, w5, w6, w7); @@ -211,9 +227,12 @@ void ffa_raise_rx_buffer_full(struct domain *d) if ( !ctx ) return; =20 - ACCESS_ONCE(ctx->notif.buff_full_pending) =3D true; - if ( !test_and_set_bool(ctx->notif.vm_pending) ) - inject_notif_pending(d); + spin_lock(&ctx->notif.notif_lock); + ctx->notif.hyp_pending |=3D FFA_NOTIF_RX_BUFFER_FULL; + if ( !ctx->notif.notif_irq_raised && + inject_notif_pending(d) ) + ctx->notif.notif_irq_raised =3D true; + spin_unlock(&ctx->notif.notif_lock); } #endif =20 @@ -426,12 +445,16 @@ void ffa_notif_init(void) =20 int ffa_notif_domain_init(struct domain *d) { + struct ffa_ctx *ctx =3D d->arch.tee; int32_t res; =20 + spin_lock_init(&ctx->notif.notif_lock); + ctx->notif.notif_irq_raised =3D false; + ctx->notif.hyp_pending =3D 0; + if ( fw_notif_enabled ) { - - res =3D ffa_notification_bitmap_create(ffa_get_vm_id(d), d->max_vc= pus); + res =3D ffa_notification_bitmap_create(ctx->ffa_id, d->max_vcpus); if ( res ) return -ENOMEM; } @@ -441,10 +464,17 @@ int ffa_notif_domain_init(struct domain *d) =20 void ffa_notif_domain_destroy(struct domain *d) { + struct ffa_ctx *ctx =3D d->arch.tee; + + spin_lock(&ctx->notif.notif_lock); + ctx->notif.notif_irq_raised =3D false; + ctx->notif.hyp_pending =3D 0; + spin_unlock(&ctx->notif.notif_lock); + /* * Call bitmap_destroy even if bitmap create failed as the SPMC will * return a DENIED error that we will ignore. */ if ( fw_notif_enabled ) - ffa_notification_bitmap_destroy(ffa_get_vm_id(d)); + ffa_notification_bitmap_destroy(ctx->ffa_id); } diff --git a/xen/arch/arm/tee/ffa_private.h b/xen/arch/arm/tee/ffa_private.h index c291f32b56ff..9ddda3f88986 100644 --- a/xen/arch/arm/tee/ffa_private.h +++ b/xen/arch/arm/tee/ffa_private.h @@ -340,9 +340,20 @@ struct ffa_ctx_notif { bool vm_pending; =20 /* - * True if domain has buffer full notification pending + * Lock protecting the hypervisor-managed notification state. */ - bool buff_full_pending; + spinlock_t notif_lock; + + /* + * Tracks whether a local notification pending interrupt was raised. + * Protected by notif_lock. + */ + bool notif_irq_raised; + + /* + * Bitmap of pending hypervisor notifications (for HYP bitmap queries). + */ + uint32_t hyp_pending; }; =20 struct ffa_ctx { --=20 2.53.0