From nobody Tue Aug 25 08:47: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=1776433319; cv=none; d=zohomail.com; s=zohoarc; b=ad5ZdhbYtTJK1zySLGumzz20zvO0H34IpXTJmAc7m79YzwU4EgHF6S26CpOCmG9ujfRP2nTCdztBp/tOvIHuSym2NeN2dtLEraKK68KgT4XNvAJXeKbDBimzaEsQyYHuShGigORuPhgILKnuLYXG2HOLM4FK1n7vMeOy+s+fB18= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1776433319; 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=ul4jGbGeuGV4A0IBk74ypHX37nRWLhWBCY6qIg9sFJo=; b=f/It8WI4XGpgXsrImJnOKpAn5NsYV3+xjHRRLFDoqkGRuTCR7jM67n9BzA7flxQvh4EioS4GNrrH4AWXM6MvW6HVdha05ZVPyEpWLrXVNQT6kD6QRasu9gnPdytTNpXe5lDs9wCweBz71tBzfP3AtsslZgy7piuiQ0KsN5KWI1M= 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 1776433319026503.9027673401132; Fri, 17 Apr 2026 06:41:59 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1284306.1566149 (Exim 4.92) (envelope-from ) id 1wDjRx-0006I3-9Y; Fri, 17 Apr 2026 13:41:37 +0000 Received: by outflank-mailman (output) from mailman id 1284306.1566149; Fri, 17 Apr 2026 13:41:37 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wDjRx-0006Hw-5i; Fri, 17 Apr 2026 13:41:37 +0000 Received: by outflank-mailman (input) for mailman id 1284306; Fri, 17 Apr 2026 13:41:35 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wDjRv-000617-Dt for xen-devel@lists.xenproject.org; Fri, 17 Apr 2026 13:41:35 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wDjRu-009kb3-Qj for xen-devel@lists.xenproject.org; Fri, 17 Apr 2026 15:41:34 +0200 Received: from [10.42.69.1] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 69e2387d-e002-0a2a0a5209dd-0a2a4501dbf6-44 for ; Fri, 17 Apr 2026 15:41:34 +0200 Received: from [217.140.110.172] (helo=foss.arm.com) by tlsNG-d62444.mxtls.expurgate.net with ESMTP (eXpurgate 4.56.1) (envelope-from ) id 69e2388e-c1f2-0a2a45010019-d98c6eacc4ba-1 for ; Fri, 17 Apr 2026 15:41:34 +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 0B3C01516; Fri, 17 Apr 2026 06:41:28 -0700 (PDT) Received: from C3HXLD123V.arm.com (unknown [10.57.89.170]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 5D90F3F7D8; Fri, 17 Apr 2026 06:41:32 -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=1776433293; bh=muz5M8Iqgy9eYpjCmc9pZ8VEHmiBcMu4FfUho63d0M0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iZTB9GDnC8dlk4AuK5JEPg+WSaTmt+qDuvHT6F6NOx2Z/7Af49FmybLRpf2vLCeJ+ ZfyhuzZXZe5xRicWkcQ64iNe5zjxp0Y/XgX38wJJYkQm1RyTIJpE5/nSVgBcMVQzfH 99YaNfJX4D5swFgq217QsO69bfIdG3TBCLtW+vmU= From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Jens Wiklander , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 4/6] xen/arm: ffa: Preserve secure notification state when polling SPMC Date: Fri, 17 Apr 2026 15:40:52 +0200 Message-ID: <5b9ce4a4a3927ce2287ec4db7f864174f53b8f17.1776266307.git.bertrand.marquis@arm.com> 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-d62444/1776433294-B5468FF4-67EDDF68/0/0 X-purgate-type: clean X-purgate-size: 7136 X-ZohoMail-DKIM: pass (identity @arm.com) X-ZM-MESSAGEID: 1776433319609158500 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 --- xen/arch/arm/tee/ffa_notif.c | 54 +++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/xen/arch/arm/tee/ffa_notif.c b/xen/arch/arm/tee/ffa_notif.c index 491db3b04df5..fff00ca2baec 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 void inject_notif_pending(struct domain *d) { @@ -109,6 +110,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 ) @@ -117,7 +119,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); @@ -131,7 +136,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); } @@ -154,6 +161,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 ) { @@ -173,27 +182,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 ) @@ -210,6 +208,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) ) @@ -354,7 +356,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: @@ -373,11 +378,18 @@ static void notif_sri_action(void *unused) unsigned int n; int32_t res; =20 - do { + if ( !fw_notif_enabled ) + return; + + 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); @@ -391,7 +403,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); @@ -399,7 +411,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); @@ -486,6 +500,7 @@ int ffa_notif_domain_init(struct domain *d) int32_t res; =20 spin_lock_init(&ctx->notif.notif_lock); + ctx->notif.secure_pending =3D false; ctx->notif.hyp_pending =3D 0; =20 if ( fw_notif_enabled ) @@ -503,6 +518,7 @@ void ffa_notif_domain_destroy(struct domain *d) struct ffa_ctx *ctx =3D d->arch.tee; =20 spin_lock(&ctx->notif.notif_lock); + ctx->notif.secure_pending =3D false; ctx->notif.hyp_pending =3D 0; spin_unlock(&ctx->notif.notif_lock); =20 --=20 2.53.0