From nobody Mon Sep 21 19:10:06 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=1777441489; cv=none; d=zohomail.com; s=zohoarc; b=J2QcQRFzVJxIcp3f4D6ibEwmGujcu+fptzoJHS2Aw8FZlZ7OCqj2mU6g7I/tIVnW86rw1A96aLsBWnBitPjZJF6WvEg4Ax+Jw13S6Ba7/kdMIDQhCICpsA8onEStw0Dg3joZN43SaTzPLgHs6Tnb48vTJfOhFdpUZ5ixAURvzWk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1777441489; 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=PyMGwFeT7o2ZhZqy5GaZVQ5SnbcYwwJ7IXmis1FNPF0=; b=Hq/FES5X1M5De7y/v5ehOZEdxLEq+EJqgyJmmPwgqdmmLhfomk9F8hRq/dFMKhc4k1qsaqKa+OHcFMOIzdhloq8gJZD/RtjT0B9dJm+ipbgButChoYKtSoYvmwyk4eVzXphEqMEGWhr/AlCOEfN5pGR3B8kKXxJ0lRzlsJfRYTQ= 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 1777441489473152.7853939807518; Tue, 28 Apr 2026 22:44:49 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1296944.1573097 (Exim 4.92) (envelope-from ) id 1wHxiW-0000Ds-Hu; Wed, 29 Apr 2026 05:44:12 +0000 Received: by outflank-mailman (output) from mailman id 1296944.1573097; Wed, 29 Apr 2026 05:44:12 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wHxiW-0000DJ-DZ; Wed, 29 Apr 2026 05:44:12 +0000 Received: by outflank-mailman (input) for mailman id 1296944; Wed, 29 Apr 2026 05:44:11 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wHxiV-00005z-L6 for xen-devel@lists.xenproject.org; Wed, 29 Apr 2026 05:44:11 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wHxiV-002Hh3-0w for xen-devel@lists.xenproject.org; Wed, 29 Apr 2026 07:44:11 +0200 Received: from [10.42.69.9] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 69f19a93-2eae-0a2a0a5409dd-0a2a45099eba-44 for ; Wed, 29 Apr 2026 07:44:11 +0200 Received: from [217.140.110.172] (helo=foss.arm.com) by tlsNG-bad1c0.mxtls.expurgate.net with ESMTP (eXpurgate 4.56.1) (envelope-from ) id 69f19aaa-2497-0a2a45090019-d98c6eaccf84-1 for ; Wed, 29 Apr 2026 07:44:10 +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 493EA2BCE; Tue, 28 Apr 2026 22:44:04 -0700 (PDT) Received: from C3HXLD123V.arm.com (unknown [10.57.90.163]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 690FD3F62B; Tue, 28 Apr 2026 22:44:08 -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=1777441449; bh=BJ9kpVORXjEmJR3F6tp4iMiyL0HijTQJTCH2Qdp2K1U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Dj6lhwGKazFYUmEf7LGtDyFsmG0A361JkJGAE9N5HVdzJvD+KQzg3+ZBzE7DmoUYq JO1RFx81+xWGobW+Dc3V3X5dJIhufRaAijA9bbV2xns+fylDh+2sFygNibL5acWcqr 8CSNKBYnGab6q8daj0JizFr7UeppPqRxPohsDMh0= From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Jens Wiklander , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v2 4/6] xen/arm: ffa: Preserve secure notification state when polling SPMC Date: Wed, 29 Apr 2026 07:43:25 +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-bad1c0/1777441450-4377AA53-000CACC7/0/0 X-purgate-type: clean X-purgate-size: 7201 X-ZohoMail-DKIM: pass (identity @arm.com) X-ZM-MESSAGEID: 1777441490164158500 Content-Type: text/plain; charset="utf-8" Secure pending state is latched when the SPMC raises the schedule receiver interrupt, but Xen currently clears that latch too aggressively. Guest FFA_NOTIFICATION_INFO_GET consumes secure_pending even though it only reports pending state, and secure FFA_NOTIFICATION_GET only clears the latch when both SP and SPM bitmaps are requested together. This can drop a pending indication before the receiver retrieves secure notifications, or keep INFO_GET reporting stale secure pending state after a successful GET. Keep secure_pending as a latched indication until secure notifications are actually retrieved. Guest FFA_NOTIFICATION_INFO_GET now reports the latched state without clearing it, while a successful secure FFA_NOTIFICATION_GET clears the latch regardless of which secure bitmap flags were requested. Also protect secure_pending with notif_lock, serialize SPMC INFO_GET polling behind notif_info_lock, and preserve the caller-visible INFO_GET success width. Functional impact: guest INFO_GET preserves the secure pending indication until secure notifications are retrieved, and successful secure GET clears the guest-visible pending latch. Signed-off-by: Bertrand Marquis Reviewed-by: Jens Wiklander --- Changes since v1: - drop the defensive fw_notif_enabled guard in notif_sri_action() --- xen/arch/arm/tee/ffa_notif.c | 51 ++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/xen/arch/arm/tee/ffa_notif.c b/xen/arch/arm/tee/ffa_notif.c index 1260f98a77e9..e1cd852d1c53 100644 --- a/xen/arch/arm/tee/ffa_notif.c +++ b/xen/arch/arm/tee/ffa_notif.c @@ -18,6 +18,7 @@ =20 static bool __ro_after_init fw_notif_enabled; static unsigned int __ro_after_init notif_sri_irq; +static DEFINE_SPINLOCK(notif_info_lock); =20 static bool inject_notif_pending(struct domain *d) { @@ -111,6 +112,7 @@ void ffa_handle_notification_info_get(struct cpu_user_r= egs *regs) { struct domain *d =3D current->domain; struct ffa_ctx *ctx =3D d->arch.tee; + uint32_t fid =3D get_user_reg(regs, 0); bool notif_pending; =20 if ( !IS_ENABLED(CONFIG_FFA_VM_TO_VM) && !fw_notif_enabled ) @@ -119,7 +121,10 @@ void ffa_handle_notification_info_get(struct cpu_user_= regs *regs) return; } =20 - notif_pending =3D test_and_clear_bool(ctx->notif.secure_pending); + spin_lock(&ctx->notif.notif_lock); + notif_pending =3D ctx->notif.secure_pending; + spin_unlock(&ctx->notif.notif_lock); + if ( IS_ENABLED(CONFIG_FFA_VM_TO_VM) ) { notif_pending |=3D test_and_clear_bool(ctx->notif.vm_pending); @@ -133,7 +138,9 @@ void ffa_handle_notification_info_get(struct cpu_user_r= egs *regs) if ( notif_pending ) { /* A pending global notification for the guest */ - ffa_set_regs(regs, FFA_SUCCESS_64, 0, + ffa_set_regs(regs, + smccc_is_conv_64(fid) ? FFA_SUCCESS_64 : FFA_SUCCESS_= 32, + 0, 1U << FFA_NOTIF_INFO_GET_ID_COUNT_SHIFT, ffa_get_vm_i= d(d), 0, 0, 0, 0); } @@ -156,6 +163,8 @@ void ffa_handle_notification_get(struct cpu_user_regs *= regs) uint32_t w5 =3D 0; uint32_t w6 =3D 0; uint32_t w7 =3D 0; + uint32_t secure_flags =3D flags & ( FFA_NOTIF_FLAG_BITMAP_SP | + FFA_NOTIF_FLAG_BITMAP_SPM ); =20 if ( !IS_ENABLED(CONFIG_FFA_VM_TO_VM) && !fw_notif_enabled ) { @@ -175,27 +184,16 @@ void ffa_handle_notification_get(struct cpu_user_regs= *regs) return; } =20 - if ( fw_notif_enabled && (flags & ( FFA_NOTIF_FLAG_BITMAP_SP | - FFA_NOTIF_FLAG_BITMAP_SPM )) ) + if ( fw_notif_enabled && secure_flags ) { struct arm_smccc_1_2_regs arg =3D { .a0 =3D FFA_NOTIFICATION_GET, .a1 =3D recv, - .a2 =3D flags & ( FFA_NOTIF_FLAG_BITMAP_SP | - FFA_NOTIF_FLAG_BITMAP_SPM ), + .a2 =3D secure_flags, }; struct arm_smccc_1_2_regs resp; int32_t e; =20 - /* - * Clear secure pending if both FFA_NOTIF_FLAG_BITMAP_SP and - * FFA_NOTIF_FLAG_BITMAP_SPM are set since secure world can't have - * any more pending notifications. - */ - if ( ( flags & FFA_NOTIF_FLAG_BITMAP_SP ) && - ( flags & FFA_NOTIF_FLAG_BITMAP_SPM ) ) - ACCESS_ONCE(ctx->notif.secure_pending) =3D false; - arm_smccc_1_2_smc(&arg, &resp); e =3D ffa_get_ret_code(&resp); if ( e ) @@ -212,6 +210,10 @@ void ffa_handle_notification_get(struct cpu_user_regs = *regs) =20 if ( flags & FFA_NOTIF_FLAG_BITMAP_SPM ) w6 =3D resp.a6; + + spin_lock(&ctx->notif.notif_lock); + ctx->notif.secure_pending =3D false; + spin_unlock(&ctx->notif.notif_lock); } =20 if ( IS_ENABLED(CONFIG_FFA_VM_TO_VM) ) @@ -356,7 +358,10 @@ static void notif_vm_pend_intr(uint16_t vm_id) * guarantees that the data structure isn't freed while we're accessing * it. */ - ACCESS_ONCE(ctx->notif.secure_pending) =3D true; + spin_lock(&ctx->notif.notif_lock); + ctx->notif.secure_pending =3D true; + spin_unlock(&ctx->notif.notif_lock); + inject_notif_pending(d); =20 out_unlock: @@ -375,11 +380,15 @@ static void notif_sri_action(void *unused) unsigned int n; int32_t res; =20 - do { + spin_lock(¬if_info_lock); + + do + { arm_smccc_1_2_smc(&arg, &resp); res =3D ffa_get_ret_code(&resp); if ( res ) { + spin_unlock(¬if_info_lock); if ( res !=3D FFA_RET_NO_DATA && printk_ratelimit() ) printk(XENLOG_WARNING "ffa: notification info get failed: error %d\n", re= s); @@ -393,7 +402,7 @@ static void notif_sri_action(void *unused) id_pos =3D 0; for ( n =3D 0; n < list_count; n++ ) { - unsigned int count =3D ((ids_count >> 2 * n) & 0x3) + 1; + unsigned int count =3D ((ids_count >> (2 * n)) & 0x3) + 1; uint16_t vm_id =3D get_id_from_resp(&resp, id_pos); =20 notif_vm_pend_intr(vm_id); @@ -401,7 +410,9 @@ static void notif_sri_action(void *unused) id_pos +=3D count; } =20 - } while (resp.a2 & FFA_NOTIF_INFO_GET_MORE_FLAG); + } while ( resp.a2 & FFA_NOTIF_INFO_GET_MORE_FLAG ); + + spin_unlock(¬if_info_lock); } =20 static DECLARE_TASKLET(notif_sri_tasklet, notif_sri_action, NULL); @@ -489,6 +500,7 @@ int ffa_notif_domain_init(struct domain *d) =20 spin_lock_init(&ctx->notif.notif_lock); ctx->notif.notif_irq_raised =3D false; + ctx->notif.secure_pending =3D false; ctx->notif.hyp_pending =3D 0; =20 if ( fw_notif_enabled ) @@ -507,6 +519,7 @@ void ffa_notif_domain_destroy(struct domain *d) =20 spin_lock(&ctx->notif.notif_lock); ctx->notif.notif_irq_raised =3D false; + ctx->notif.secure_pending =3D false; ctx->notif.hyp_pending =3D 0; spin_unlock(&ctx->notif.notif_lock); =20 --=20 2.53.0