From nobody Sat Feb 7 07:31:33 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; 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=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 17701403444601017.2414663323419; Tue, 3 Feb 2026 09:39:04 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1219538.1528412 (Exim 4.92) (envelope-from ) id 1vnKMR-0000sG-Dz; Tue, 03 Feb 2026 17:38:47 +0000 Received: by outflank-mailman (output) from mailman id 1219538.1528412; Tue, 03 Feb 2026 17:38:47 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMR-0000s6-9V; Tue, 03 Feb 2026 17:38:47 +0000 Received: by outflank-mailman (input) for mailman id 1219538; Tue, 03 Feb 2026 17:38:45 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMP-0000Zt-EA for xen-devel@lists.xenproject.org; Tue, 03 Feb 2026 17:38:45 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 2edc0ddb-0127-11f1-9ccf-f158ae23cfc8; Tue, 03 Feb 2026 18:38:43 +0100 (CET) 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 C66EC339; Tue, 3 Feb 2026 09:38:35 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.54.220]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 281583F632; Tue, 3 Feb 2026 09:38:41 -0800 (PST) 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" X-Inumbo-ID: 2edc0ddb-0127-11f1-9ccf-f158ae23cfc8 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Jens Wiklander , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 01/12] xen/arm: ffa: Add endpoint lookup helper Date: Tue, 3 Feb 2026 18:37:56 +0100 Message-ID: X-Mailer: git-send-email 2.51.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1770140347217154100 Content-Type: text/plain; charset="utf-8" Direct messaging paths duplicate endpoint validation and RCU domain lookup logic across multiple call sites, which makes the checks easy to drift and complicates maintenance. Introduce ffa_endpoint_domain_lookup() to centralize this logic. The helper validates the endpoint ID (rejecting ID 0 for the hypervisor), performs RCU domain lookup, ensures the domain is live and has an initialized FF-A context with a negotiated version, and returns the domain locked via RCU. Switch ffa_msg_send2_vm() to use the helper, replacing its open-coded validation sequence. This consolidates approximately 20 lines of duplicated checks into a single call. No functional changes. Signed-off-by: Bertrand Marquis Reviewed-by: Jens Wiklander --- xen/arch/arm/tee/ffa.c | 45 ++++++++++++++++++++++++++++++++++ xen/arch/arm/tee/ffa_msg.c | 24 +++--------------- xen/arch/arm/tee/ffa_private.h | 3 +++ 3 files changed, 51 insertions(+), 21 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index ed18e76080d0..6de2b9f8ac8e 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -433,6 +433,51 @@ static bool ffa_handle_call(struct cpu_user_regs *regs) return true; } =20 +/* + * Look up a domain by its FF-A endpoint ID and validate it's ready for FF= -A. + * Returns FFA_RET_OK on success with domain locked via RCU. + * Caller must call rcu_unlock_domain() when done. + * + * Validates: + * - endpoint_id is not 0 (the hypervisor) + * - domain exists and is live + * - domain has FF-A context initialized + * - domain has negotiated an FF-A version + */ +int32_t ffa_endpoint_domain_lookup(uint16_t endpoint_id, struct domain **d= _out, + struct ffa_ctx **ctx_out) +{ + struct domain *d; + struct ffa_ctx *ctx; + int err; + + if ( endpoint_id =3D=3D 0 ) + return FFA_RET_INVALID_PARAMETERS; + + err =3D rcu_lock_live_remote_domain_by_id(endpoint_id - 1, &d); + if ( err ) + return FFA_RET_INVALID_PARAMETERS; + + if ( !d->arch.tee ) + { + rcu_unlock_domain(d); + return FFA_RET_INVALID_PARAMETERS; + } + + ctx =3D d->arch.tee; + if ( !ACCESS_ONCE(ctx->guest_vers) ) + { + rcu_unlock_domain(d); + return FFA_RET_INVALID_PARAMETERS; + } + + *d_out =3D d; + if ( ctx_out ) + *ctx_out =3D ctx; + + return FFA_RET_OK; +} + static int ffa_domain_init(struct domain *d) { struct ffa_ctx *ctx; diff --git a/xen/arch/arm/tee/ffa_msg.c b/xen/arch/arm/tee/ffa_msg.c index 4e26596461a9..10856fddcbc4 100644 --- a/xen/arch/arm/tee/ffa_msg.c +++ b/xen/arch/arm/tee/ffa_msg.c @@ -161,30 +161,12 @@ static int32_t ffa_msg_send2_vm(uint16_t dst_id, cons= t void *src_buf, struct ffa_part_msg_rxtx_1_2 *dst_msg; void *rx_buf; size_t rx_size; - int err; int32_t ret; =20 - if ( dst_id =3D=3D 0 ) - /* FF-A ID 0 is the hypervisor, this is not valid */ - return FFA_RET_INVALID_PARAMETERS; - /* This is also checking that dest is not src */ - err =3D rcu_lock_live_remote_domain_by_id(dst_id - 1, &dst_d); - if ( err ) - return FFA_RET_INVALID_PARAMETERS; - - if ( dst_d->arch.tee =3D=3D NULL ) - { - ret =3D FFA_RET_INVALID_PARAMETERS; - goto out_unlock; - } - - dst_ctx =3D dst_d->arch.tee; - if ( !ACCESS_ONCE(dst_ctx->guest_vers) ) - { - ret =3D FFA_RET_INVALID_PARAMETERS; - goto out_unlock; - } + ret =3D ffa_endpoint_domain_lookup(dst_id, &dst_d, &dst_ctx); + if ( ret ) + return ret; =20 /* This also checks that destination has set a Rx buffer */ ret =3D ffa_rx_acquire(dst_ctx , &rx_buf, &rx_size); diff --git a/xen/arch/arm/tee/ffa_private.h b/xen/arch/arm/tee/ffa_private.h index 282c105f3bce..cd7ecabc7eff 100644 --- a/xen/arch/arm/tee/ffa_private.h +++ b/xen/arch/arm/tee/ffa_private.h @@ -437,6 +437,9 @@ int32_t ffa_partinfo_domain_init(struct domain *d); bool ffa_partinfo_domain_destroy(struct domain *d); void ffa_handle_partition_info_get(struct cpu_user_regs *regs); =20 +int32_t ffa_endpoint_domain_lookup(uint16_t endpoint_id, struct domain **d= _out, + struct ffa_ctx **ctx_out); + bool ffa_rxtx_spmc_init(void); void ffa_rxtx_spmc_destroy(void); void *ffa_rxtx_spmc_rx_acquire(void); --=20 2.50.1 (Apple Git-155) From nobody Sat Feb 7 07:31:33 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; 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=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1770140347704597.9014404434796; Tue, 3 Feb 2026 09:39:07 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1219537.1528401 (Exim 4.92) (envelope-from ) id 1vnKMQ-0000eU-6J; Tue, 03 Feb 2026 17:38:46 +0000 Received: by outflank-mailman (output) from mailman id 1219537.1528401; Tue, 03 Feb 2026 17:38:46 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMQ-0000eN-3Q; Tue, 03 Feb 2026 17:38:46 +0000 Received: by outflank-mailman (input) for mailman id 1219537; Tue, 03 Feb 2026 17:38:44 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMO-0000KW-Ml for xen-devel@lists.xenproject.org; Tue, 03 Feb 2026 17:38:44 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 2fa3276b-0127-11f1-b161-2bf370ae4941; Tue, 03 Feb 2026 18:38:44 +0100 (CET) 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 32C8C497; Tue, 3 Feb 2026 09:38:37 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.54.220]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 904F73F632; Tue, 3 Feb 2026 09:38:42 -0800 (PST) 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" X-Inumbo-ID: 2fa3276b-0127-11f1-b161-2bf370ae4941 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Jens Wiklander , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 02/12] xen/arm: ffa: Fix MEM_SHARE NS attribute handling Date: Tue, 3 Feb 2026 18:37:57 +0100 Message-ID: <9886df295f4c4365668576cc956299ee36f36c8b.1770115301.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.51.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1770140348986154100 Content-Type: text/plain; charset="utf-8" The FF-A memory attribute encoding is currently a literal value (0x2f), which makes reviews and validation harder. In addition, MEM_SHARE accepts the NS (non-secure) attribute bit even though the normal world must not set it according to FF-A specification. Introduce named attribute bit masks and express FFA_NORMAL_MEM_REG_ATTR in terms of them for clarity. Reject MEM_SHARE descriptors with the NS bit set, returning INVALID_PARAMETERS to match FF-A v1.1 rules that prohibit normal world from setting this bit. Functional impact: MEM_SHARE now rejects descriptors with NS bit set, which were previously accepted but violate FF-A specification. Signed-off-by: Bertrand Marquis --- xen/arch/arm/tee/ffa_private.h | 17 ++++++++++++++++- xen/arch/arm/tee/ffa_shm.c | 6 ++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/tee/ffa_private.h b/xen/arch/arm/tee/ffa_private.h index cd7ecabc7eff..b625f1c72914 100644 --- a/xen/arch/arm/tee/ffa_private.h +++ b/xen/arch/arm/tee/ffa_private.h @@ -129,11 +129,26 @@ #define FFA_HANDLE_HYP_FLAG BIT(63, ULL) #define FFA_HANDLE_INVALID 0xffffffffffffffffULL =20 +/* NS attribute was introduced in v1.1 */ +#define FFA_MEM_ATTR_NS BIT(6, U) + +#define FFA_MEM_ATTR_TYPE_DEV (1U << 3) +#define FFA_MEM_ATTR_TYPE_MEM (2U << 4) + +#define FFA_MEM_ATTR_NC (1U << 2) +#define FFA_MEM_ATTR_WB (3U << 2) + +#define FFA_MEM_ATTR_NON_SHARE (0U) +#define FFA_MEM_ATTR_OUT_SHARE (2U) +#define FFA_MEM_ATTR_INN_SHARE (3U) + /* * Memory attributes: Normal memory, Write-Back cacheable, Inner shareable * Defined in FF-A-1.1-REL0 Table 10.18 at page 175. */ -#define FFA_NORMAL_MEM_REG_ATTR 0x2fU +#define FFA_NORMAL_MEM_REG_ATTR (FFA_MEM_ATTR_TYPE_MEM | \ + FFA_MEM_ATTR_WB | \ + FFA_MEM_ATTR_INN_SHARE) /* * Memory access permissions: Read-write * Defined in FF-A-1.1-REL0 Table 10.15 at page 168. diff --git a/xen/arch/arm/tee/ffa_shm.c b/xen/arch/arm/tee/ffa_shm.c index 8282bacf85d3..90800e44a86a 100644 --- a/xen/arch/arm/tee/ffa_shm.c +++ b/xen/arch/arm/tee/ffa_shm.c @@ -512,6 +512,12 @@ void ffa_handle_mem_share(struct cpu_user_regs *regs) if ( ret ) goto out_unlock; =20 + if ( trans.mem_reg_attr & FFA_MEM_ATTR_NS ) + { + ret =3D FFA_RET_INVALID_PARAMETERS; + goto out_unlock; + } + if ( trans.mem_reg_attr !=3D FFA_NORMAL_MEM_REG_ATTR ) { ret =3D FFA_RET_NOT_SUPPORTED; --=20 2.50.1 (Apple Git-155) From nobody Sat Feb 7 07:31:33 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; 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=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1770140349565304.42970191942504; Tue, 3 Feb 2026 09:39:09 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1219539.1528423 (Exim 4.92) (envelope-from ) id 1vnKMT-0001B3-Mn; Tue, 03 Feb 2026 17:38:49 +0000 Received: by outflank-mailman (output) from mailman id 1219539.1528423; Tue, 03 Feb 2026 17:38:49 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMT-0001Au-Gp; Tue, 03 Feb 2026 17:38:49 +0000 Received: by outflank-mailman (input) for mailman id 1219539; Tue, 03 Feb 2026 17:38:47 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMR-0000Zt-Ow for xen-devel@lists.xenproject.org; Tue, 03 Feb 2026 17:38:47 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 3082c8e9-0127-11f1-9ccf-f158ae23cfc8; Tue, 03 Feb 2026 18:38:45 +0100 (CET) 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 A181C1063; Tue, 3 Feb 2026 09:38:38 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.54.220]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id DE5CF3F632; Tue, 3 Feb 2026 09:38:43 -0800 (PST) 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" X-Inumbo-ID: 3082c8e9-0127-11f1-9ccf-f158ae23cfc8 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Jens Wiklander , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 03/12] xen/arm: ffa: Harden shm page parsing Date: Tue, 3 Feb 2026 18:37:58 +0100 Message-ID: <97a064c81ee5ea26774c189538f9f1e37dd3eebc.1770115302.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.51.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1770140350989154100 Content-Type: text/plain; charset="utf-8" get_shm_pages() uses unchecked address arithmetic and does not enforce alignment, so malformed descriptors can cause overflow or slip through validation. The reclaim path also repeats handle-to-shm-mem conversion in multiple places, duplicating error handling. Harden page parsing and reclaim handling: - add ffa_safe_addr_add() and use it to detect address overflows - enforce alignment checks in get_shm_pages() and return FF-A errors - introduce ffa_secure_reclaim() and use it for MEM_RECLAIM and teardown - simplify ffa_mem_share() argument handling and allow max page count Functional impact: invalid or misaligned memory ranges now fail earlier with proper error codes; behavior for valid descriptors is unchanged. Signed-off-by: Bertrand Marquis --- xen/arch/arm/tee/ffa_private.h | 11 +++++++ xen/arch/arm/tee/ffa_shm.c | 57 +++++++++++++++++----------------- 2 files changed, 40 insertions(+), 28 deletions(-) diff --git a/xen/arch/arm/tee/ffa_private.h b/xen/arch/arm/tee/ffa_private.h index b625f1c72914..58562d8e733c 100644 --- a/xen/arch/arm/tee/ffa_private.h +++ b/xen/arch/arm/tee/ffa_private.h @@ -632,4 +632,15 @@ static inline void ffa_uuid_set(struct ffa_uuid *id, u= int32_t val0, id->val[1] =3D ((uint64_t)val3 << 32U) | val2; } =20 +/* + * Common overflow-safe helper to verify that adding a number of pages to = an + * address will not wrap around. + */ +static inline bool ffa_safe_addr_add(uint64_t addr, uint64_t pages) +{ + uint64_t off =3D pages * FFA_PAGE_SIZE; + + return (off / FFA_PAGE_SIZE) =3D=3D pages && addr <=3D UINT64_MAX - of= f; +} + #endif /*__FFA_PRIVATE_H__*/ diff --git a/xen/arch/arm/tee/ffa_shm.c b/xen/arch/arm/tee/ffa_shm.c index 90800e44a86a..4c0b45cde6ee 100644 --- a/xen/arch/arm/tee/ffa_shm.c +++ b/xen/arch/arm/tee/ffa_shm.c @@ -96,16 +96,14 @@ struct ffa_shm_mem { struct page_info *pages[]; }; =20 -static int32_t ffa_mem_share(uint32_t tot_len, uint32_t frag_len, - register_t addr, uint32_t pg_count, - uint64_t *handle) +static int32_t ffa_mem_share(uint32_t tot_len, uint64_t *handle) { struct arm_smccc_1_2_regs arg =3D { .a0 =3D FFA_MEM_SHARE_64, .a1 =3D tot_len, - .a2 =3D frag_len, - .a3 =3D addr, - .a4 =3D pg_count, + .a2 =3D tot_len, + .a3 =3D 0, + .a4 =3D 0, }; struct arm_smccc_1_2_regs resp; =20 @@ -131,12 +129,16 @@ static int32_t ffa_mem_share(uint32_t tot_len, uint32= _t frag_len, } } =20 -static int32_t ffa_mem_reclaim(uint32_t handle_lo, uint32_t handle_hi, - uint32_t flags) +static int32_t ffa_secure_reclaim(struct ffa_shm_mem *shm, uint32_t flags) { + register_t handle_hi; + register_t handle_lo; + if ( !ffa_fw_supports_fid(FFA_MEM_RECLAIM) ) return FFA_RET_NOT_SUPPORTED; =20 + uint64_to_regpair(&handle_hi, &handle_lo, shm->handle); + return ffa_simple_call(FFA_MEM_RECLAIM, handle_lo, handle_hi, flags, 0= ); } =20 @@ -145,7 +147,7 @@ static int32_t ffa_mem_reclaim(uint32_t handle_lo, uint= 32_t handle_hi, * this function fails then the caller is still expected to call * put_shm_pages() as a cleanup. */ -static int get_shm_pages(struct domain *d, struct ffa_shm_mem *shm, +static int32_t get_shm_pages(struct domain *d, struct ffa_shm_mem *shm, const struct ffa_address_range *range, uint32_t range_count) { @@ -156,17 +158,26 @@ static int get_shm_pages(struct domain *d, struct ffa= _shm_mem *shm, p2m_type_t t; uint64_t addr; uint64_t page_count; + uint64_t gaddr; =20 for ( n =3D 0; n < range_count; n++ ) { page_count =3D ACCESS_ONCE(range[n].page_count); addr =3D ACCESS_ONCE(range[n].address); + + if ( !IS_ALIGNED(addr, FFA_PAGE_SIZE) ) + return FFA_RET_INVALID_PARAMETERS; + for ( m =3D 0; m < page_count; m++ ) { if ( pg_idx >=3D shm->page_count ) return FFA_RET_INVALID_PARAMETERS; =20 - gfn =3D gaddr_to_gfn(addr + m * FFA_PAGE_SIZE); + if ( !ffa_safe_addr_add(addr, m) ) + return FFA_RET_INVALID_PARAMETERS; + + gaddr =3D addr + m * FFA_PAGE_SIZE; + gfn =3D gaddr_to_gfn(gaddr); shm->pages[pg_idx] =3D get_page_from_gfn(d, gfn_x(gfn), &t, P2M_ALLOC); if ( !shm->pages[pg_idx] ) @@ -180,7 +191,7 @@ static int get_shm_pages(struct domain *d, struct ffa_s= hm_mem *shm, =20 /* The ranges must add up */ if ( pg_idx < shm->page_count ) - return FFA_RET_INVALID_PARAMETERS; + return FFA_RET_INVALID_PARAMETERS; =20 return FFA_RET_OK; } @@ -198,15 +209,11 @@ static void put_shm_pages(struct ffa_shm_mem *shm) =20 static bool inc_ctx_shm_count(struct domain *d, struct ffa_ctx *ctx) { - bool ret =3D true; + bool ret =3D false; =20 spin_lock(&ctx->lock); =20 - if ( ctx->shm_count >=3D FFA_MAX_SHM_COUNT ) - { - ret =3D false; - } - else + if ( ctx->shm_count < FFA_MAX_SHM_COUNT ) { /* * If this is the first shm added, increase the domain reference @@ -217,6 +224,7 @@ static bool inc_ctx_shm_count(struct domain *d, struct = ffa_ctx *ctx) get_knownalive_domain(d); =20 ctx->shm_count++; + ret =3D true; } =20 spin_unlock(&ctx->lock); @@ -251,7 +259,7 @@ static struct ffa_shm_mem *alloc_ffa_shm_mem(struct dom= ain *d, struct ffa_ctx *ctx =3D d->arch.tee; struct ffa_shm_mem *shm; =20 - if ( page_count >=3D FFA_MAX_SHM_PAGE_COUNT ) + if ( page_count > FFA_MAX_SHM_PAGE_COUNT ) return NULL; if ( !inc_ctx_shm_count(d, ctx) ) return NULL; @@ -367,7 +375,7 @@ static int share_shm(struct ffa_shm_mem *shm) init_range(addr_range, pa); } =20 - ret =3D ffa_mem_share(tot_len, frag_len, 0, 0, &shm->handle); + ret =3D ffa_mem_share(tot_len, &shm->handle); =20 out: ffa_rxtx_spmc_tx_release(); @@ -637,8 +645,6 @@ int32_t ffa_handle_mem_reclaim(uint64_t handle, uint32_= t flags) struct domain *d =3D current->domain; struct ffa_ctx *ctx =3D d->arch.tee; struct ffa_shm_mem *shm; - register_t handle_hi; - register_t handle_lo; int32_t ret; =20 if ( !ffa_fw_supports_fid(FFA_MEM_RECLAIM) ) @@ -652,8 +658,7 @@ int32_t ffa_handle_mem_reclaim(uint64_t handle, uint32_= t flags) if ( !shm ) return FFA_RET_INVALID_PARAMETERS; =20 - uint64_to_regpair(&handle_hi, &handle_lo, handle); - ret =3D ffa_mem_reclaim(handle_lo, handle_hi, flags); + ret =3D ffa_secure_reclaim(shm, flags); =20 if ( ret ) { @@ -677,11 +682,7 @@ bool ffa_shm_domain_destroy(struct domain *d) =20 list_for_each_entry_safe(shm, tmp, &ctx->shm_list, list) { - register_t handle_hi; - register_t handle_lo; - - uint64_to_regpair(&handle_hi, &handle_lo, shm->handle); - res =3D ffa_mem_reclaim(handle_lo, handle_hi, 0); + res =3D ffa_secure_reclaim(shm, 0); switch ( res ) { case FFA_RET_OK: printk(XENLOG_G_DEBUG "%pd: ffa: Reclaimed handle %#lx\n", --=20 2.50.1 (Apple Git-155) From nobody Sat Feb 7 07:31:33 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; 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=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1770140356433443.9691066110943; Tue, 3 Feb 2026 09:39:16 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1219540.1528428 (Exim 4.92) (envelope-from ) id 1vnKMU-0001H8-3D; Tue, 03 Feb 2026 17:38:50 +0000 Received: by outflank-mailman (output) from mailman id 1219540.1528428; Tue, 03 Feb 2026 17:38:50 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMT-0001Fc-US; Tue, 03 Feb 2026 17:38:49 +0000 Received: by outflank-mailman (input) for mailman id 1219540; Tue, 03 Feb 2026 17:38:49 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMT-0000Zt-4y for xen-devel@lists.xenproject.org; Tue, 03 Feb 2026 17:38:49 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 315067dd-0127-11f1-9ccf-f158ae23cfc8; Tue, 03 Feb 2026 18:38:47 +0100 (CET) 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 000A0150C; Tue, 3 Feb 2026 09:38:39 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.54.220]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 5699A3F632; Tue, 3 Feb 2026 09:38:45 -0800 (PST) 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" X-Inumbo-ID: 315067dd-0127-11f1-9ccf-f158ae23cfc8 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Jens Wiklander , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 04/12] xen/arm: ffa: Add FF-A 1.2 endpoint memory access descriptors Date: Tue, 3 Feb 2026 18:37:59 +0100 Message-ID: X-Mailer: git-send-email 2.51.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1770140359187154100 Content-Type: text/plain; charset="utf-8" FF-A 1.2 extends the endpoint memory access descriptor (EMAD) from 16 to 32 bytes, adding implementation-defined (IMPDEF) fields and reserved space. The MEM_SHARE path currently assumes the 1.1 EMAD size and rejects the 1.2 layout. Add FF-A 1.2 EMAD support to MEM_SHARE: - define ffa_mem_access_1_2 and store IMPDEF payload in ffa_shm_mem - emit 1.2 EMADs to the SPMC for FF-A 1.2 guests, forwarding IMPDEF - refactor header parsing into read_mem_transaction() for 1.0/1.1+ - detect EMAD format by mem_access_size to allow 1.1 on 1.2 guests Functional impact: MEM_SHARE supports FF-A 1.2 EMADs. Signed-off-by: Bertrand Marquis --- xen/arch/arm/tee/ffa_shm.c | 108 +++++++++++++++++++++++++++++-------- 1 file changed, 86 insertions(+), 22 deletions(-) diff --git a/xen/arch/arm/tee/ffa_shm.c b/xen/arch/arm/tee/ffa_shm.c index 4c0b45cde6ee..905a64e3db01 100644 --- a/xen/arch/arm/tee/ffa_shm.c +++ b/xen/arch/arm/tee/ffa_shm.c @@ -30,6 +30,14 @@ struct ffa_mem_access { uint64_t reserved; }; =20 +/* Endpoint memory access descriptor (FF-A 1.2) */ +struct ffa_mem_access_1_2 { + struct ffa_mem_access_perm access_perm; + uint32_t region_offs; + uint8_t impdef[16]; + uint8_t reserved[8]; +}; + /* Lend, donate or share memory transaction descriptor */ struct ffa_mem_transaction_1_0 { uint16_t sender_id; @@ -73,7 +81,7 @@ struct ffa_mem_transaction_1_1 { /* * The parts needed from struct ffa_mem_transaction_1_0 or struct * ffa_mem_transaction_1_1, used to provide an abstraction of difference in - * data structures between version 1.0 and 1.1. This is just an internal + * data structures between version 1.0 and 1.2. This is just an internal * interface and can be changed without changing any ABI. */ struct ffa_mem_transaction_int { @@ -92,6 +100,8 @@ struct ffa_shm_mem { uint16_t sender_id; uint16_t ep_id; /* endpoint, the one lending */ uint64_t handle; /* FFA_HANDLE_INVALID if not set yet */ + /* Endpoint memory access descriptor IMPDEF value (FF-A 1.2). */ + uint64_t impdef[2]; unsigned int page_count; struct page_info *pages[]; }; @@ -297,17 +307,21 @@ static void init_range(struct ffa_address_range *addr= _range, * This function uses the ffa_spmc tx buffer to transmit the memory transa= ction * descriptor. */ -static int share_shm(struct ffa_shm_mem *shm) +static int share_shm(struct ffa_shm_mem *shm, uint32_t ffa_vers) { const uint32_t max_frag_len =3D FFA_RXTX_PAGE_COUNT * FFA_PAGE_SIZE; struct ffa_mem_access *mem_access_array; + struct ffa_mem_access_1_2 *mem_access_array_1_2; struct ffa_mem_transaction_1_1 *descr; struct ffa_address_range *addr_range; struct ffa_mem_region *region_descr; - const unsigned int region_count =3D 1; uint32_t frag_len; uint32_t tot_len; + uint32_t mem_access_size; + uint32_t mem_access_offs; + uint32_t region_offs; paddr_t last_pa; + uint32_t range_count; unsigned int n; paddr_t pa; int32_t ret; @@ -326,16 +340,35 @@ static int share_shm(struct ffa_shm_mem *shm) descr->handle =3D shm->handle; descr->mem_reg_attr =3D FFA_NORMAL_MEM_REG_ATTR; descr->mem_access_count =3D 1; - descr->mem_access_size =3D sizeof(*mem_access_array); - descr->mem_access_offs =3D MEM_ACCESS_OFFSET(0); + if ( ffa_vers >=3D FFA_VERSION_1_2 ) + mem_access_size =3D sizeof(struct ffa_mem_access_1_2); + else + mem_access_size =3D sizeof(struct ffa_mem_access); + mem_access_offs =3D sizeof(struct ffa_mem_transaction_1_1); + region_offs =3D mem_access_offs + mem_access_size; + descr->mem_access_size =3D mem_access_size; + descr->mem_access_offs =3D mem_access_offs; =20 - mem_access_array =3D buf + descr->mem_access_offs; - memset(mem_access_array, 0, sizeof(*mem_access_array)); - mem_access_array[0].access_perm.endpoint_id =3D shm->ep_id; - mem_access_array[0].access_perm.perm =3D FFA_MEM_ACC_RW; - mem_access_array[0].region_offs =3D REGION_OFFSET(descr->mem_access_co= unt, 0); + if ( ffa_vers >=3D FFA_VERSION_1_2 ) + { + mem_access_array_1_2 =3D buf + mem_access_offs; + memset(mem_access_array_1_2, 0, sizeof(*mem_access_array_1_2)); + mem_access_array_1_2[0].access_perm.endpoint_id =3D shm->ep_id; + mem_access_array_1_2[0].access_perm.perm =3D FFA_MEM_ACC_RW; + mem_access_array_1_2[0].region_offs =3D region_offs; + memcpy(mem_access_array_1_2[0].impdef, shm->impdef, + sizeof(mem_access_array_1_2[0].impdef)); + } + else + { + mem_access_array =3D buf + mem_access_offs; + memset(mem_access_array, 0, sizeof(*mem_access_array)); + mem_access_array[0].access_perm.endpoint_id =3D shm->ep_id; + mem_access_array[0].access_perm.perm =3D FFA_MEM_ACC_RW; + mem_access_array[0].region_offs =3D region_offs; + } =20 - region_descr =3D buf + mem_access_array[0].region_offs; + region_descr =3D buf + region_offs; memset(region_descr, 0, sizeof(*region_descr)); region_descr->total_page_count =3D shm->page_count; =20 @@ -349,8 +382,9 @@ static int share_shm(struct ffa_shm_mem *shm) region_descr->address_range_count++; } =20 - tot_len =3D ADDR_RANGE_OFFSET(descr->mem_access_count, region_count, - region_descr->address_range_count); + range_count =3D region_descr->address_range_count; + tot_len =3D region_offs + sizeof(*region_descr) + + range_count * sizeof(struct ffa_address_range); if ( tot_len > max_frag_len ) { ret =3D FFA_RET_NOT_SUPPORTED; @@ -358,7 +392,7 @@ static int share_shm(struct ffa_shm_mem *shm) } =20 addr_range =3D region_descr->address_range_array; - frag_len =3D ADDR_RANGE_OFFSET(descr->mem_access_count, region_count, = 1); + frag_len =3D region_offs + sizeof(*region_descr) + sizeof(*addr_range); last_pa =3D page_to_maddr(shm->pages[0]); init_range(addr_range, last_pa); for ( n =3D 1; n < shm->page_count; last_pa =3D pa, n++ ) @@ -448,6 +482,12 @@ static int read_mem_transaction(uint32_t ffa_vers, con= st void *buf, size_t blen, if ( size * count + offs > blen ) return FFA_RET_INVALID_PARAMETERS; =20 + if ( size < sizeof(struct ffa_mem_access) ) + return FFA_RET_INVALID_PARAMETERS; + + if ( offs & 0xF ) + return FFA_RET_INVALID_PARAMETERS; + trans->mem_reg_attr =3D mem_reg_attr; trans->flags =3D flags; trans->mem_access_size =3D size; @@ -464,7 +504,7 @@ void ffa_handle_mem_share(struct cpu_user_regs *regs) uint64_t addr =3D get_user_reg(regs, 3); uint32_t page_count =3D get_user_reg(regs, 4); const struct ffa_mem_region *region_descr; - const struct ffa_mem_access *mem_access; + const struct ffa_mem_access_1_2 *mem_access; struct ffa_mem_transaction_int trans; struct domain *d =3D current->domain; struct ffa_ctx *ctx =3D d->arch.tee; @@ -474,9 +514,12 @@ void ffa_handle_mem_share(struct cpu_user_regs *regs) register_t handle_hi =3D 0; register_t handle_lo =3D 0; int ret =3D FFA_RET_DENIED; + uint32_t ffa_vers; uint32_t range_count; uint32_t region_offs; uint16_t dst_id; + uint8_t perm; + uint64_t impdef[2]; =20 if ( !ffa_fw_supports_fid(FFA_MEM_SHARE_64) ) { @@ -515,8 +558,8 @@ void ffa_handle_mem_share(struct cpu_user_regs *regs) if ( frag_len > tx_size ) goto out_unlock; =20 - ret =3D read_mem_transaction(ACCESS_ONCE(ctx->guest_vers), tx_buf, - frag_len, &trans); + ffa_vers =3D ACCESS_ONCE(ctx->guest_vers); + ret =3D read_mem_transaction(ffa_vers, tx_buf, frag_len, &trans); if ( ret ) goto out_unlock; =20 @@ -545,13 +588,35 @@ void ffa_handle_mem_share(struct cpu_user_regs *regs) goto out_unlock; } =20 + if ( trans.mem_access_size < sizeof(struct ffa_mem_access) ) + { + ret =3D FFA_RET_INVALID_PARAMETERS; + goto out_unlock; + } + /* Check that it fits in the supplied data */ if ( trans.mem_access_offs + trans.mem_access_size > frag_len ) goto out_unlock; =20 mem_access =3D tx_buf + trans.mem_access_offs; - dst_id =3D ACCESS_ONCE(mem_access->access_perm.endpoint_id); + perm =3D ACCESS_ONCE(mem_access->access_perm.perm); + region_offs =3D ACCESS_ONCE(mem_access->region_offs); + + /* + * FF-A 1.2 introduced an extended mem_access descriptor with impdef + * fields, but guests can still use the 1.1 format if they don't need + * implementation-defined data. Detect which format is used based on + * the mem_access_size field rather than the negotiated FF-A version. + */ + if ( trans.mem_access_size >=3D sizeof(struct ffa_mem_access_1_2) ) + memcpy(impdef, mem_access->impdef, sizeof(impdef)); + else + { + impdef[0] =3D 0; + impdef[1] =3D 0; + } + if ( !FFA_ID_IS_SECURE(dst_id) ) { /* we do not support sharing with VMs */ @@ -559,13 +624,11 @@ void ffa_handle_mem_share(struct cpu_user_regs *regs) goto out_unlock; } =20 - if ( ACCESS_ONCE(mem_access->access_perm.perm) !=3D FFA_MEM_ACC_RW ) + if ( perm !=3D FFA_MEM_ACC_RW ) { ret =3D FFA_RET_NOT_SUPPORTED; goto out_unlock; } - - region_offs =3D ACCESS_ONCE(mem_access->region_offs); if ( sizeof(*region_descr) + region_offs > frag_len ) { ret =3D FFA_RET_NOT_SUPPORTED; @@ -590,6 +653,7 @@ void ffa_handle_mem_share(struct cpu_user_regs *regs) } shm->sender_id =3D trans.sender_id; shm->ep_id =3D dst_id; + memcpy(shm->impdef, impdef, sizeof(shm->impdef)); =20 /* * Check that the Composite memory region descriptor fits. @@ -605,7 +669,7 @@ void ffa_handle_mem_share(struct cpu_user_regs *regs) if ( ret ) goto out; =20 - ret =3D share_shm(shm); + ret =3D share_shm(shm, ffa_vers); if ( ret ) goto out; =20 --=20 2.50.1 (Apple Git-155) From nobody Sat Feb 7 07:31:33 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; 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=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1770140349049430.89895255023316; Tue, 3 Feb 2026 09:39:09 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1219541.1528442 (Exim 4.92) (envelope-from ) id 1vnKMV-0001d6-Fr; Tue, 03 Feb 2026 17:38:51 +0000 Received: by outflank-mailman (output) from mailman id 1219541.1528442; Tue, 03 Feb 2026 17:38:51 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMV-0001cv-9J; Tue, 03 Feb 2026 17:38:51 +0000 Received: by outflank-mailman (input) for mailman id 1219541; Tue, 03 Feb 2026 17:38:50 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMU-0000Zt-5Q for xen-devel@lists.xenproject.org; Tue, 03 Feb 2026 17:38:50 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 321b6341-0127-11f1-9ccf-f158ae23cfc8; Tue, 03 Feb 2026 18:38:48 +0100 (CET) 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 71FDA497; Tue, 3 Feb 2026 09:38:41 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.54.220]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id BF6933F632; Tue, 3 Feb 2026 09:38:46 -0800 (PST) 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" X-Inumbo-ID: 321b6341-0127-11f1-9ccf-f158ae23cfc8 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Jens Wiklander , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 05/12] xen/arm: ffa: Fix PARTINFO RX release errors Date: Tue, 3 Feb 2026 18:38:00 +0100 Message-ID: <2cb24d49d7c72bf15a101cc3be62b3cccbfce3d5.1770115302.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.51.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1770140350959154100 Content-Type: text/plain; charset="utf-8" On PARTITION_INFO_GET error paths, Xen unconditionally called FFA_RX_RELEASE for the SPMC RX buffer. If the SPMC didn't grant RX ownership (i.e., the call failed early), this issues a spurious release that returns DENIED and produces warnings. Modify ffa_rxtx_spmc_rx_release() to return the release status and let callers choose whether to log it. Only issue FFA_RX_RELEASE after a successful PARTINFO SMC, while always releasing the local RX lock to avoid deadlocks. Update handle_partition_info_get() to only release the SPMC RX buffer after successful fw_ret checks, and ignore release errors during the error path. Functional impact: eliminates spurious FFA_RX_RELEASE calls and associated DENIED warnings when PARTITION_INFO_GET fails before obtaining SPMC RX buffer ownership. Signed-off-by: Bertrand Marquis --- xen/arch/arm/tee/ffa_partinfo.c | 14 ++++++++++++-- xen/arch/arm/tee/ffa_private.h | 2 +- xen/arch/arm/tee/ffa_rxtx.c | 14 +++++++++----- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/xen/arch/arm/tee/ffa_partinfo.c b/xen/arch/arm/tee/ffa_partinf= o.c index bf906ed0c88f..6b01c4abe915 100644 --- a/xen/arch/arm/tee/ffa_partinfo.c +++ b/xen/arch/arm/tee/ffa_partinfo.c @@ -92,9 +92,11 @@ static int32_t ffa_get_sp_partinfo(struct ffa_uuid uuid,= uint32_t *sp_count, uint32_t dst_size) { int32_t ret; + int32_t release_ret; uint32_t src_size, real_sp_count; void *src_buf; uint32_t count =3D 0; + bool spmc_ok =3D false; =20 /* We need to use the RX buffer to receive the list */ src_buf =3D ffa_rxtx_spmc_rx_acquire(); @@ -104,6 +106,7 @@ static int32_t ffa_get_sp_partinfo(struct ffa_uuid uuid= , uint32_t *sp_count, ret =3D ffa_partition_info_get(uuid, 0, &real_sp_count, &src_size); if ( ret ) goto out; + spmc_ok =3D true; =20 /* Validate the src_size we got */ if ( src_size < sizeof(struct ffa_partition_info_1_0) || @@ -157,7 +160,10 @@ static int32_t ffa_get_sp_partinfo(struct ffa_uuid uui= d, uint32_t *sp_count, *sp_count =3D count; =20 out: - ffa_rxtx_spmc_rx_release(); + release_ret =3D ffa_rxtx_spmc_rx_release(spmc_ok); + if ( release_ret ) + gprintk(XENLOG_WARNING, + "ffa: Error releasing SPMC RX buffer: %d\n", release_ret); return ret; } =20 @@ -507,6 +513,7 @@ bool ffa_partinfo_init(void) int32_t e; void *spmc_rx; struct ffa_uuid nil_uuid =3D { .val =3D { 0ULL, 0ULL } }; + bool spmc_ok =3D false; =20 if ( !ffa_fw_supports_fid(FFA_PARTITION_INFO_GET) || !ffa_fw_supports_fid(FFA_MSG_SEND_DIRECT_REQ_32)) @@ -522,6 +529,7 @@ bool ffa_partinfo_init(void) printk(XENLOG_ERR "ffa: Failed to get list of SPs: %d\n", e); goto out; } + spmc_ok =3D true; =20 if ( count >=3D FFA_MAX_NUM_SP ) { @@ -533,7 +541,9 @@ bool ffa_partinfo_init(void) ret =3D init_subscribers(spmc_rx, count, fpi_size); =20 out: - ffa_rxtx_spmc_rx_release(); + e =3D ffa_rxtx_spmc_rx_release(spmc_ok); + if ( e ) + printk(XENLOG_WARNING "ffa: Error releasing SPMC RX buffer: %d\n",= e); return ret; } =20 diff --git a/xen/arch/arm/tee/ffa_private.h b/xen/arch/arm/tee/ffa_private.h index 58562d8e733c..461e87f6f9c4 100644 --- a/xen/arch/arm/tee/ffa_private.h +++ b/xen/arch/arm/tee/ffa_private.h @@ -458,7 +458,7 @@ int32_t ffa_endpoint_domain_lookup(uint16_t endpoint_id= , struct domain **d_out, bool ffa_rxtx_spmc_init(void); void ffa_rxtx_spmc_destroy(void); void *ffa_rxtx_spmc_rx_acquire(void); -void ffa_rxtx_spmc_rx_release(void); +int32_t ffa_rxtx_spmc_rx_release(bool notify_fw); void *ffa_rxtx_spmc_tx_acquire(void); void ffa_rxtx_spmc_tx_release(void); =20 diff --git a/xen/arch/arm/tee/ffa_rxtx.c b/xen/arch/arm/tee/ffa_rxtx.c index 7d8bb4f4d031..50758fb57cdf 100644 --- a/xen/arch/arm/tee/ffa_rxtx.c +++ b/xen/arch/arm/tee/ffa_rxtx.c @@ -375,18 +375,22 @@ void *ffa_rxtx_spmc_rx_acquire(void) return NULL; } =20 -void ffa_rxtx_spmc_rx_release(void) +int32_t ffa_rxtx_spmc_rx_release(bool notify_fw) { int32_t ret; =20 ASSERT(spin_is_locked(&ffa_spmc_rx_lock)); =20 - /* Inform the SPMC that we are done with our RX buffer */ - ret =3D ffa_simple_call(FFA_RX_RELEASE, 0, 0, 0, 0); - if ( ret !=3D FFA_RET_OK ) - printk(XENLOG_DEBUG "Error releasing SPMC RX buffer: %d\n", ret); + if ( notify_fw ) + { + /* Inform the SPMC that we are done with our RX buffer */ + ret =3D ffa_simple_call(FFA_RX_RELEASE, 0, 0, 0, 0); + } + else + ret =3D FFA_RET_OK; =20 spin_unlock(&ffa_spmc_rx_lock); + return ret; } =20 void *ffa_rxtx_spmc_tx_acquire(void) --=20 2.50.1 (Apple Git-155) From nobody Sat Feb 7 07:31:33 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; 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=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1770140355987306.26227110082164; Tue, 3 Feb 2026 09:39:15 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1219542.1528451 (Exim 4.92) (envelope-from ) id 1vnKMW-0001u3-Kv; Tue, 03 Feb 2026 17:38:52 +0000 Received: by outflank-mailman (output) from mailman id 1219542.1528451; Tue, 03 Feb 2026 17:38:52 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMW-0001tF-I5; Tue, 03 Feb 2026 17:38:52 +0000 Received: by outflank-mailman (input) for mailman id 1219542; Tue, 03 Feb 2026 17:38:51 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMV-0000Zt-9h for xen-devel@lists.xenproject.org; Tue, 03 Feb 2026 17:38:51 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 32eca68a-0127-11f1-9ccf-f158ae23cfc8; Tue, 03 Feb 2026 18:38:49 +0100 (CET) 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 D6359339; Tue, 3 Feb 2026 09:38:42 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.54.220]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 3ADB03F632; Tue, 3 Feb 2026 09:38:48 -0800 (PST) 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" X-Inumbo-ID: 32eca68a-0127-11f1-9ccf-f158ae23cfc8 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Jens Wiklander , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 06/12] xen/arm: ffa: Fix RX/TX map layout and errors Date: Tue, 3 Feb 2026 18:38:01 +0100 Message-ID: X-Mailer: git-send-email 2.51.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1770140356769158501 Content-Type: text/plain; charset="utf-8" FFA_RXTX_MAP builds a descriptor for the SPMC and the composite region offsets must be 8-byte aligned. Xen currently uses a 12-byte header size, which produces misaligned RX/TX offsets. Mapping failures also return INVALID_PARAMETERS even when the failure is due to resource exhaustion, which misreports the error condition. Round the descriptor header size up to 8 bytes before placing the RX region and derive the TX offset from the aligned RX offset. Return FFA_RET_NO_MEMORY when the TX or RX buffer mapping fails before the error paths unwind. Functional impact: RXTX_MAP now returns NO_MEMORY on mapping failures and the SPMC receives an aligned RX/TX descriptor layout. Signed-off-by: Bertrand Marquis --- xen/arch/arm/tee/ffa_rxtx.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/xen/arch/arm/tee/ffa_rxtx.c b/xen/arch/arm/tee/ffa_rxtx.c index 50758fb57cdf..eff95a7955d7 100644 --- a/xen/arch/arm/tee/ffa_rxtx.c +++ b/xen/arch/arm/tee/ffa_rxtx.c @@ -119,11 +119,17 @@ int32_t ffa_handle_rxtx_map(uint32_t fid, register_t = tx_addr, =20 tx =3D __map_domain_page_global(tx_pg); if ( !tx ) + { + ret =3D FFA_RET_NO_MEMORY; goto err_put_rx_pg; + } =20 rx =3D __map_domain_page_global(rx_pg); if ( !rx ) + { + ret =3D FFA_RET_NO_MEMORY; goto err_unmap_tx; + } =20 /* * Transmit the RX/TX buffer information to the SPM if acquire is supp= orted @@ -136,7 +142,8 @@ int32_t ffa_handle_rxtx_map(uint32_t fid, register_t tx= _addr, struct ffa_mem_region *mem_reg; =20 /* All must fit in our TX buffer */ - BUILD_BUG_ON(sizeof(*rxtx_desc) + sizeof(*mem_reg) * 2 + + BUILD_BUG_ON(ROUNDUP(sizeof(*rxtx_desc), 8) + + sizeof(*mem_reg) * 2 + sizeof(struct ffa_address_range) * 2 > FFA_MAX_RXTX_PAGE_COUNT * FFA_PAGE_SIZE); =20 @@ -153,8 +160,8 @@ int32_t ffa_handle_rxtx_map(uint32_t fid, register_t tx= _addr, */ rxtx_desc->sender_id =3D ffa_get_vm_id(d); rxtx_desc->reserved =3D 0; - rxtx_desc->rx_region_offs =3D sizeof(*rxtx_desc); - rxtx_desc->tx_region_offs =3D sizeof(*rxtx_desc) + + rxtx_desc->rx_region_offs =3D ROUNDUP(sizeof(*rxtx_desc), 8); + rxtx_desc->tx_region_offs =3D rxtx_desc->rx_region_offs + offsetof(struct ffa_mem_region, address_range_array[1]); =20 --=20 2.50.1 (Apple Git-155) From nobody Sat Feb 7 07:31:33 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; 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=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 177014035436345.34875123975735; Tue, 3 Feb 2026 09:39:14 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1219545.1528461 (Exim 4.92) (envelope-from ) id 1vnKMY-0002Eg-Sd; Tue, 03 Feb 2026 17:38:54 +0000 Received: by outflank-mailman (output) from mailman id 1219545.1528461; Tue, 03 Feb 2026 17:38:54 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMY-0002EX-PG; Tue, 03 Feb 2026 17:38:54 +0000 Received: by outflank-mailman (input) for mailman id 1219545; Tue, 03 Feb 2026 17:38:53 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMX-0000Zt-5S for xen-devel@lists.xenproject.org; Tue, 03 Feb 2026 17:38:53 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 33bb85be-0127-11f1-9ccf-f158ae23cfc8; Tue, 03 Feb 2026 18:38:51 +0100 (CET) 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 30E051063; Tue, 3 Feb 2026 09:38:44 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.54.220]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 89D673F632; Tue, 3 Feb 2026 09:38:49 -0800 (PST) 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" X-Inumbo-ID: 33bb85be-0127-11f1-9ccf-f158ae23cfc8 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Jens Wiklander , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 07/12] xen/arm: ffa: Fix RXTX_UNMAP ownership race Date: Tue, 3 Feb 2026 18:38:02 +0100 Message-ID: <971bf27b9a2cafa0ed405a638a532b6fbbf51142.1770115302.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.51.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1770140356936158500 Content-Type: text/plain; charset="utf-8" rxtx_unmap() checks RX ownership without holding the RX/TX locks and only enforces the ownership rule when FFA_RX_ACQUIRE is supported. This allows a vCPU to acquire RX between the check and unmap, and it lets RXTX_UNMAP proceed while RX is owned when buffers are not forwarded to firmware. Hold rx_lock/tx_lock across the ownership check and unmap, and deny RXTX_UNMAP whenever RX is owned, independent of RX_ACQUIRE support. For teardown, release RX ownership under the same lock window; use FFA_RX_RELEASE directly because rx_lock is held, and clear the local flag when the firmware path is unavailable. Functional impact: RXTX_UNMAP now reliably returns DENIED while RX is owned, and teardown releases/clears ownership without a race. Signed-off-by: Bertrand Marquis --- xen/arch/arm/tee/ffa_rxtx.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/xen/arch/arm/tee/ffa_rxtx.c b/xen/arch/arm/tee/ffa_rxtx.c index eff95a7955d7..450ce102cbdc 100644 --- a/xen/arch/arm/tee/ffa_rxtx.c +++ b/xen/arch/arm/tee/ffa_rxtx.c @@ -220,7 +220,7 @@ err_unlock_rxtx: return ret; } =20 -static int32_t rxtx_unmap(struct domain *d) +static int32_t rxtx_unmap(struct domain *d, bool teardown) { struct ffa_ctx *ctx =3D d->arch.tee; int32_t ret =3D FFA_RET_OK; @@ -234,6 +234,36 @@ static int32_t rxtx_unmap(struct domain *d) goto err_unlock_rxtx; } =20 + if ( !ctx->rx_is_free ) + { + if ( teardown ) + { + if ( ffa_fw_supports_fid(FFA_RX_ACQUIRE) ) + { + int32_t rel_ret; + + /* Can't use ffa_rx_release() while holding rx_lock. */ + rel_ret =3D ffa_simple_call(FFA_RX_RELEASE, ctx->ffa_id, + 0, 0, 0); + if ( rel_ret ) + gdprintk(XENLOG_DEBUG, + "ffa: RX release during teardown failed: %d\n= ", + rel_ret); + else + ctx->rx_is_free =3D true; + } + else + ctx->rx_is_free =3D true; + } + else + { + gdprintk(XENLOG_DEBUG, + "ffa: RXTX_UNMAP denied, RX buffer owned by VM\n"); + ret =3D FFA_RET_DENIED; + goto err_unlock_rxtx; + } + } + if ( ffa_fw_supports_fid(FFA_RX_ACQUIRE) ) { ret =3D ffa_rxtx_unmap(ffa_get_vm_id(d)); @@ -261,7 +291,7 @@ err_unlock_rxtx: =20 int32_t ffa_handle_rxtx_unmap(void) { - return rxtx_unmap(current->domain); + return rxtx_unmap(current->domain, false); } =20 int32_t ffa_rx_acquire(struct ffa_ctx *ctx, void **buf, size_t *buf_size) @@ -369,7 +399,7 @@ int32_t ffa_rxtx_domain_init(struct domain *d) =20 void ffa_rxtx_domain_destroy(struct domain *d) { - rxtx_unmap(d); + rxtx_unmap(d, true); } =20 void *ffa_rxtx_spmc_rx_acquire(void) --=20 2.50.1 (Apple Git-155) From nobody Sat Feb 7 07:31:33 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; 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=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1770140355311273.61628475016903; Tue, 3 Feb 2026 09:39:15 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1219549.1528473 (Exim 4.92) (envelope-from ) id 1vnKMa-0002U5-5x; Tue, 03 Feb 2026 17:38:56 +0000 Received: by outflank-mailman (output) from mailman id 1219549.1528473; Tue, 03 Feb 2026 17:38:56 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMa-0002TW-0H; Tue, 03 Feb 2026 17:38:56 +0000 Received: by outflank-mailman (input) for mailman id 1219549; Tue, 03 Feb 2026 17:38:54 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMY-0000Zt-Pm for xen-devel@lists.xenproject.org; Tue, 03 Feb 2026 17:38:54 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 347a7422-0127-11f1-9ccf-f158ae23cfc8; Tue, 03 Feb 2026 18:38:52 +0100 (CET) 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 7201A150C; Tue, 3 Feb 2026 09:38:45 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.54.220]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id D84193F632; Tue, 3 Feb 2026 09:38:50 -0800 (PST) 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" X-Inumbo-ID: 347a7422-0127-11f1-9ccf-f158ae23cfc8 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Jens Wiklander , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 08/12] xen/arm: ffa: Fix FFA_FEATURES validation Date: Tue, 3 Feb 2026 18:38:03 +0100 Message-ID: <5331b33343441028d10c290b21b82acce295fff0.1770115302.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.51.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1770140356961158500 Content-Type: text/plain; charset="utf-8" FFA_FEATURES currently accepts non-zero input properties (w2-w7) from guests and advertises several ABIs unconditionally, even when firmware support is missing or when the ABI is physical-instance-only. This can mislead guests about what Xen can actually provide and violates FF-A calling conventions. Some SPMCs (Hafnium v2.14 or earlier) also fail to report FFA_RX_ACQUIRE despite supporting it. Update FFA_FEATURES validation to match spec and firmware support: - reject non-zero w2-w7 input properties with INVALID_PARAMETERS - reject 64-bit calling conventions from 32-bit guests with NOT_SUPPORTED - return NOT_SUPPORTED for physical-instance-only ABIs (FFA_NOTIFICATION_BITMAP_{CREATE,DESTROY}, FFA_RX_ACQUIRE) - advertise FFA_INTERRUPT as supported - gate message ABIs on firmware support: - FFA_MSG_SEND_DIRECT_REQ_{32,64} - FFA_MSG_SEND_DIRECT_REQ2 (also requires FF-A 1.2 negotiation) - FFA_MSG_SEND2 (or VM-to-VM enabled) - report MEM_SHARE_{32,64} only when FFA_MEM_SHARE_64 is supported - stop advertising FFA_MSG_YIELD (not implemented) Update firmware probing: drop FFA_MEM_SHARE_32 checks (deprecated) and add FFA_RX_ACQUIRE to the probed set. If FFA_MSG_SEND2 is reported but FFA_RX_ACQUIRE is not, assume RX_ACQUIRE support and warn to work around the Hafnium bug. Functional impact: guests now see ABI support that reflects firmware capabilities and Xen implementation status. When SEND2 is present but RX_ACQUIRE is not reported, Xen assumes RX_ACQUIRE support. Signed-off-by: Bertrand Marquis --- xen/arch/arm/tee/ffa.c | 62 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index 6de2b9f8ac8e..e9e020bb0cb3 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -91,10 +91,10 @@ static const struct ffa_fw_abi ffa_fw_abi_needed[] =3D { FW_ABI(FFA_PARTITION_INFO_GET), FW_ABI(FFA_NOTIFICATION_INFO_GET_64), FW_ABI(FFA_NOTIFICATION_GET), + FW_ABI(FFA_RX_ACQUIRE), FW_ABI(FFA_RX_RELEASE), FW_ABI(FFA_RXTX_MAP_64), FW_ABI(FFA_RXTX_UNMAP), - FW_ABI(FFA_MEM_SHARE_32), FW_ABI(FFA_MEM_SHARE_64), FW_ABI(FFA_MEM_RECLAIM), FW_ABI(FFA_MSG_SEND_DIRECT_REQ_32), @@ -240,19 +240,39 @@ static void handle_features(struct cpu_user_regs *reg= s) struct ffa_ctx *ctx =3D d->arch.tee; unsigned int n; =20 + /* + * Xen does not accept any non-zero FFA_FEATURES input properties from + * VMs. The spec only defines w2 input properties for FFA_MEM_RETRIEVE= _REQ + * (NS-bit negotiation for SP/SPMC) and FFA_RXTX_MAP (buffer size and + * alignment), so w2 must be MBZ for our callers. + */ for ( n =3D 2; n <=3D 7; n++ ) { if ( get_user_reg(regs, n) ) { - ffa_set_regs_error(regs, FFA_RET_NOT_SUPPORTED); + ffa_set_regs_error(regs, FFA_RET_INVALID_PARAMETERS); return; } } =20 + if ( !is_64bit_domain(d) && smccc_is_conv_64(a1) ) + { + /* 32bit guests should only use 32bit convention calls */ + ffa_set_regs_error(regs, FFA_RET_NOT_SUPPORTED); + return; + } + switch ( a1 ) { + case FFA_NOTIFICATION_BITMAP_CREATE: + case FFA_NOTIFICATION_BITMAP_DESTROY: + case FFA_RX_ACQUIRE: + /* Physical-instance-only ABIs are not exposed to VMs. */ + ffa_set_regs_error(regs, FFA_RET_NOT_SUPPORTED); + break; case FFA_ERROR: case FFA_VERSION: + case FFA_INTERRUPT: case FFA_SUCCESS_32: case FFA_SUCCESS_64: case FFA_FEATURES: @@ -261,16 +281,25 @@ static void handle_features(struct cpu_user_regs *reg= s) case FFA_RXTX_UNMAP: case FFA_MEM_RECLAIM: case FFA_PARTITION_INFO_GET: + ffa_set_regs_success(regs, 0, 0); + break; case FFA_MSG_SEND_DIRECT_REQ_32: case FFA_MSG_SEND_DIRECT_REQ_64: - case FFA_MSG_SEND2: case FFA_RUN: - case FFA_INTERRUPT: - case FFA_MSG_YIELD: - ffa_set_regs_success(regs, 0, 0); + if ( ffa_fw_supports_fid(a1) ) + ffa_set_regs_success(regs, 0, 0); + else + ffa_set_regs_error(regs, FFA_RET_NOT_SUPPORTED); + break; + case FFA_MSG_SEND2: + if ( ffa_fw_supports_fid(a1) || IS_ENABLED(CONFIG_FFA_VM_TO_VM) ) + ffa_set_regs_success(regs, 0, 0); + else + ffa_set_regs_error(regs, FFA_RET_NOT_SUPPORTED); break; case FFA_MSG_SEND_DIRECT_REQ2: - if ( ACCESS_ONCE(ctx->guest_vers) >=3D FFA_VERSION_1_2 ) + if ( ACCESS_ONCE(ctx->guest_vers) >=3D FFA_VERSION_1_2 && + ffa_fw_supports_fid(FFA_MSG_SEND_DIRECT_REQ2) ) { ffa_set_regs_success(regs, 0, 0); } @@ -281,6 +310,11 @@ static void handle_features(struct cpu_user_regs *regs) break; case FFA_MEM_SHARE_64: case FFA_MEM_SHARE_32: + if ( !ffa_fw_supports_fid(FFA_MEM_SHARE_64) ) + { + ffa_set_regs_error(regs, FFA_RET_NOT_SUPPORTED); + break; + } /* * We currently don't support dynamically allocated buffers. Report * that with 0 in bit[0] of w2. @@ -688,6 +722,20 @@ static bool ffa_probe_fw(void) ffa_fw_abi_needed[i].name); } =20 + /* + * Hafnium v2.14 or earlier does not report FFA_RX_ACQUIRE in + * FFA_FEATURES even though it supports it. + */ + if ( !ffa_fw_supports_fid(FFA_RX_ACQUIRE) && + ffa_fw_supports_fid(FFA_MSG_SEND2) ) + { + printk(XENLOG_WARNING + "ARM FF-A Firmware reports FFA_MSG_SEND2 without FFA_RX_ACQ= UIRE\n"); + printk(XENLOG_WARNING + "ffa: assuming RX_ACQUIRE support (workaround)\n"); + set_bit(FFA_ABI_BITNUM(FFA_RX_ACQUIRE), ffa_fw_abi_supported); + } + if ( !ffa_rxtx_spmc_init() ) { printk(XENLOG_ERR "ffa: Error during RXTX buffer init\n"); --=20 2.50.1 (Apple Git-155) From nobody Sat Feb 7 07:31:33 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; 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=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1770140866749728.6132099318685; Tue, 3 Feb 2026 09:47:46 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1219614.1528497 (Exim 4.92) (envelope-from ) id 1vnKUn-0006LY-Ok; Tue, 03 Feb 2026 17:47:25 +0000 Received: by outflank-mailman (output) from mailman id 1219614.1528497; Tue, 03 Feb 2026 17:47:25 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKUn-0006KU-Js; Tue, 03 Feb 2026 17:47:25 +0000 Received: by outflank-mailman (input) for mailman id 1219614; Tue, 03 Feb 2026 17:47:23 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMZ-0000Zt-Q7 for xen-devel@lists.xenproject.org; Tue, 03 Feb 2026 17:38:55 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 35442268-0127-11f1-9ccf-f158ae23cfc8; Tue, 03 Feb 2026 18:38:53 +0100 (CET) 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 BD3931063; Tue, 3 Feb 2026 09:38:46 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.54.220]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 27CF83F632; Tue, 3 Feb 2026 09:38:52 -0800 (PST) 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" X-Inumbo-ID: 35442268-0127-11f1-9ccf-f158ae23cfc8 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Jens Wiklander , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 09/12] xen/arm: ffa: Fix SEND2 SP support gating Date: Tue, 3 Feb 2026 18:38:04 +0100 Message-ID: <9466059cffcae65acb96a6c3710778f2e9ebcbbd.1770115302.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.51.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1770140868674154100 Content-Type: text/plain; charset="utf-8" Xen only maps a VM RX/TX buffer into the SPMC when firmware supports FFA_RX_ACQUIRE. Without that mapping, the SPMC cannot access the VM TX buffer to relay FFA_MSG_SEND2 to a secure partition. Advertise FFA_MSG_SEND2 to guests only when VM-to-VM is enabled or when the firmware supports both FFA_MSG_SEND2 and FFA_RX_ACQUIRE, and reject SEND2 to a secure partition otherwise. Add comments to document the mapping/ownership dependency. Functional impact: SEND2 to a secure partition is reported as NOT_SUPPORTED when FFA_RX_ACQUIRE is absent. Signed-off-by: Bertrand Marquis --- xen/arch/arm/tee/ffa.c | 8 +++++++- xen/arch/arm/tee/ffa_msg.c | 11 +++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index e9e020bb0cb3..a46c6e5e67f1 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -292,7 +292,13 @@ static void handle_features(struct cpu_user_regs *regs) ffa_set_regs_error(regs, FFA_RET_NOT_SUPPORTED); break; case FFA_MSG_SEND2: - if ( ffa_fw_supports_fid(a1) || IS_ENABLED(CONFIG_FFA_VM_TO_VM) ) + /* + * Forwarding SEND2 to an SP requires the SPMC to see the VM TX bu= ffer. + * We only map VM RX/TX into the SPMC when RX_ACQUIRE is supported. + */ + if ( IS_ENABLED(CONFIG_FFA_VM_TO_VM) || + (ffa_fw_supports_fid(FFA_MSG_SEND2) && + ffa_fw_supports_fid(FFA_RX_ACQUIRE)) ) ffa_set_regs_success(regs, 0, 0); else ffa_set_regs_error(regs, FFA_RET_NOT_SUPPORTED); diff --git a/xen/arch/arm/tee/ffa_msg.c b/xen/arch/arm/tee/ffa_msg.c index 10856fddcbc4..928f269f6c3a 100644 --- a/xen/arch/arm/tee/ffa_msg.c +++ b/xen/arch/arm/tee/ffa_msg.c @@ -274,6 +274,17 @@ int32_t ffa_handle_msg_send2(struct cpu_user_regs *reg= s) ret =3D FFA_RET_NOT_SUPPORTED; goto out; } + /* + * The SPMC needs access to the VM TX buffer to relay SEND2. + * We only map VM RX/TX into the SPMC when RX_ACQUIRE is supported. + */ + if ( !ffa_fw_supports_fid(FFA_RX_ACQUIRE) ) + { + ret =3D FFA_RET_NOT_SUPPORTED; + gdprintk(XENLOG_DEBUG, + "ffa: msg_send2 to SP requires RX_ACQUIRE\n"); + goto out; + } =20 ret =3D ffa_simple_call(FFA_MSG_SEND2, ((uint32_t)ffa_get_vm_id(src_d)) << 16, 0, 0= , 0); --=20 2.50.1 (Apple Git-155) From nobody Sat Feb 7 07:31:33 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; 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=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1770140865317886.5992685234368; Tue, 3 Feb 2026 09:47:45 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1219609.1528483 (Exim 4.92) (envelope-from ) id 1vnKUm-00065c-BP; Tue, 03 Feb 2026 17:47:24 +0000 Received: by outflank-mailman (output) from mailman id 1219609.1528483; Tue, 03 Feb 2026 17:47:24 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKUm-00065V-5y; Tue, 03 Feb 2026 17:47:24 +0000 Received: by outflank-mailman (input) for mailman id 1219609; Tue, 03 Feb 2026 17:47:22 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMb-0000Zt-QJ for xen-devel@lists.xenproject.org; Tue, 03 Feb 2026 17:38:57 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 3616fea1-0127-11f1-9ccf-f158ae23cfc8; Tue, 03 Feb 2026 18:38:54 +0100 (CET) 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 33F89339; Tue, 3 Feb 2026 09:38:48 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.54.220]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 76D9F3F632; Tue, 3 Feb 2026 09:38:53 -0800 (PST) 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" X-Inumbo-ID: 3616fea1-0127-11f1-9ccf-f158ae23cfc8 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Jens Wiklander , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 10/12] xen/arm: ffa: Reduce logging noise Date: Tue, 3 Feb 2026 18:38:05 +0100 Message-ID: <38d71ac53abeeb4598d6ffb6bdab3717b3531334.1770115302.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.51.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1770140867843158500 Content-Type: text/plain; charset="utf-8" Several FF-A paths log warnings for expected or recoverable conditions, leading to noisy logs during normal operation. Reduce log noise by: - demoting unhandled FID warnings to debug - ratelimiting notification and VM teardown failures - printing the bit-15 convention warning once per boot - adjusting log prefixes for hypervisor-only events - adding debug diagnostics for RX/TX acquire failures, with busy cases ratelimited No functional changes. Signed-off-by: Bertrand Marquis --- xen/arch/arm/tee/ffa.c | 11 ++++++----- xen/arch/arm/tee/ffa_notif.c | 11 ++++++----- xen/arch/arm/tee/ffa_partinfo.c | 15 ++++++++------- xen/arch/arm/tee/ffa_rxtx.c | 21 +++++++++++++++++++-- 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index a46c6e5e67f1..d0b9c9f1ab2e 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -461,7 +461,7 @@ static bool ffa_handle_call(struct cpu_user_regs *regs) break; =20 default: - gprintk(XENLOG_ERR, "ffa: unhandled fid 0x%x\n", fid); + gdprintk(XENLOG_DEBUG, "ffa: unhandled fid 0x%x\n", fid); e =3D FFA_RET_NOT_SUPPORTED; break; } @@ -581,7 +581,8 @@ static void ffa_domain_teardown_continue(struct ffa_ctx= *ctx, bool first_time) =20 if ( retry ) { - printk(XENLOG_G_INFO "%pd: ffa: Remaining cleanup, retrying\n", ct= x->teardown_d); + printk(XENLOG_G_DEBUG "%pd: ffa: Remaining cleanup, retrying\n", + ctx->teardown_d); =20 ctx->teardown_expire =3D NOW() + FFA_CTX_TEARDOWN_DELAY; =20 @@ -622,7 +623,7 @@ static void ffa_teardown_timer_callback(void *arg) if ( ctx ) ffa_domain_teardown_continue(ctx, false /* !first_time */); else - printk(XENLOG_G_ERR "%s: teardown list is empty\n", __func__); + printk(XENLOG_ERR "%s: teardown list is empty\n", __func__); } =20 /* This function is supposed to undo what ffa_domain_init() has done */ @@ -684,7 +685,7 @@ static bool ffa_probe_fw(void) =20 if ( !ffa_get_version(&vers) ) { - gprintk(XENLOG_ERR, "Cannot retrieve the FFA version\n"); + printk(XENLOG_ERR "ffa: Cannot retrieve the FFA version\n"); goto err_no_fw; } =20 @@ -724,7 +725,7 @@ static bool ffa_probe_fw(void) set_bit(FFA_ABI_BITNUM(ffa_fw_abi_needed[i].id), ffa_fw_abi_supported); else - printk(XENLOG_INFO "ARM FF-A Firmware does not support %s\n", + printk(XENLOG_WARNING "ARM FF-A Firmware does not support %s\n= ", ffa_fw_abi_needed[i].name); } =20 diff --git a/xen/arch/arm/tee/ffa_notif.c b/xen/arch/arm/tee/ffa_notif.c index 37b05747cd21..186e72641237 100644 --- a/xen/arch/arm/tee/ffa_notif.c +++ b/xen/arch/arm/tee/ffa_notif.c @@ -292,8 +292,9 @@ static void notif_vm_pend_intr(uint16_t vm_id) break; } } - if ( !v ) - printk(XENLOG_ERR "ffa: can't inject NPI, all vCPUs offline\n"); + if ( !v && printk_ratelimit() ) + printk(XENLOG_G_DEBUG "%pd: ffa: can't inject NPI, all vCPUs offli= ne\n", + d); =20 out_unlock: rcu_unlock_domain(d); @@ -316,9 +317,9 @@ static void notif_sri_action(void *unused) res =3D ffa_get_ret_code(&resp); if ( res ) { - if ( res !=3D FFA_RET_NO_DATA ) - printk(XENLOG_ERR "ffa: notification info get failed: erro= r %d\n", - res); + if ( res !=3D FFA_RET_NO_DATA && printk_ratelimit() ) + printk(XENLOG_WARNING + "ffa: notification info get failed: error %d\n", re= s); return; } =20 diff --git a/xen/arch/arm/tee/ffa_partinfo.c b/xen/arch/arm/tee/ffa_partinf= o.c index 6b01c4abe915..c9f186b3720c 100644 --- a/xen/arch/arm/tee/ffa_partinfo.c +++ b/xen/arch/arm/tee/ffa_partinfo.c @@ -461,9 +461,11 @@ static bool init_subscribers(void *buf, uint16_t count= , uint32_t fpi_size) */ if ( !FFA_ID_IS_SECURE(fpi->id) ) { - printk(XENLOG_ERR "ffa: Firmware is not using bit 15 conventio= n for IDs !!\n" - "ffa: Secure partition with id 0x%04x cannot= be used\n", - fpi->id); + printk_once(XENLOG_ERR + "ffa: Firmware is not using bit 15 convention for = IDs !!\n"); + printk(XENLOG_ERR + "ffa: Secure partition with id 0x%04x cannot be used\n", + fpi->id); } else { @@ -632,11 +634,10 @@ bool ffa_partinfo_domain_destroy(struct domain *d) res =3D ffa_direct_req_send_vm(subscr_vm_destroyed[n], ffa_get_vm_= id(d), FFA_MSG_SEND_VM_DESTROYED); =20 - if ( res ) - { - printk(XENLOG_ERR "%pd: ffa: Failed to report destruction of v= m_id %u to %u: res %d\n", + if ( res && printk_ratelimit() ) + printk(XENLOG_WARNING + "%pd: ffa: Failed to report destruction of vm_id %u to = %u: res %d\n", d, ffa_get_vm_id(d), subscr_vm_destroyed[n], res); - } =20 /* * For these two error codes the hypervisor is expected to resend diff --git a/xen/arch/arm/tee/ffa_rxtx.c b/xen/arch/arm/tee/ffa_rxtx.c index 450ce102cbdc..3147aba21ddf 100644 --- a/xen/arch/arm/tee/ffa_rxtx.c +++ b/xen/arch/arm/tee/ffa_rxtx.c @@ -4,6 +4,7 @@ */ =20 #include +#include #include #include #include @@ -82,8 +83,9 @@ int32_t ffa_handle_rxtx_map(uint32_t fid, register_t tx_a= ddr, =20 if ( page_count > FFA_MAX_RXTX_PAGE_COUNT || !page_count ) { - printk(XENLOG_ERR "ffa: RXTX_MAP: error: %u pages requested (limit= %u)\n", - page_count, FFA_MAX_RXTX_PAGE_COUNT); + gdprintk(XENLOG_DEBUG, + "ffa: RXTX_MAP: error: %u pages requested (limit %u)\n", + page_count, FFA_MAX_RXTX_PAGE_COUNT); return FFA_RET_INVALID_PARAMETERS; } =20 @@ -303,12 +305,15 @@ int32_t ffa_rx_acquire(struct ffa_ctx *ctx, void **bu= f, size_t *buf_size) if ( !ctx->page_count ) { ret =3D FFA_RET_DENIED; + gdprintk(XENLOG_DEBUG, "ffa: RX acquire denied, no RX/TX mapped\n"= ); goto out; } =20 if ( !ctx->rx_is_free ) { ret =3D FFA_RET_BUSY; + if ( printk_ratelimit() ) + gdprintk(XENLOG_DEBUG, "ffa: RX acquire busy\n"); goto out; } =20 @@ -316,7 +321,10 @@ int32_t ffa_rx_acquire(struct ffa_ctx *ctx, void **buf= , size_t *buf_size) { ret =3D ffa_simple_call(FFA_RX_ACQUIRE, ctx->ffa_id, 0, 0, 0); if ( ret !=3D FFA_RET_OK ) + { + gdprintk(XENLOG_DEBUG, "ffa: RX acquire failed: %d\n", ret); goto out; + } } ctx->rx_is_free =3D false; *buf =3D ctx->rx; @@ -355,13 +363,22 @@ int32_t ffa_tx_acquire(struct ffa_ctx *ctx, const voi= d **buf, size_t *buf_size) int32_t ret =3D FFA_RET_DENIED; =20 if ( !spin_trylock(&ctx->tx_lock) ) + { + gdprintk(XENLOG_DEBUG, "ffa: TX acquire busy\n"); return FFA_RET_BUSY; + } =20 if ( !ctx->page_count ) + { + gdprintk(XENLOG_DEBUG, "ffa: TX acquire denied, no RX/TX mapped\n"= ); goto err_unlock; + } =20 if ( !ctx->tx ) + { + gdprintk(XENLOG_DEBUG, "ffa: TX acquire denied, TX buffer missing\= n"); goto err_unlock; + } =20 *buf =3D ctx->tx; *buf_size =3D ctx->page_count * FFA_PAGE_SIZE; --=20 2.50.1 (Apple Git-155) From nobody Sat Feb 7 07:31:33 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; 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=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1770140865576476.5131000062888; Tue, 3 Feb 2026 09:47:45 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1219612.1528492 (Exim 4.92) (envelope-from ) id 1vnKUn-0006JD-Gp; Tue, 03 Feb 2026 17:47:25 +0000 Received: by outflank-mailman (output) from mailman id 1219612.1528492; Tue, 03 Feb 2026 17:47:25 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKUn-0006J6-Cj; Tue, 03 Feb 2026 17:47:25 +0000 Received: by outflank-mailman (input) for mailman id 1219612; Tue, 03 Feb 2026 17:47:23 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMe-0000Zt-R6 for xen-devel@lists.xenproject.org; Tue, 03 Feb 2026 17:39:00 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 36fa34b3-0127-11f1-9ccf-f158ae23cfc8; Tue, 03 Feb 2026 18:38:56 +0100 (CET) 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 84871497; Tue, 3 Feb 2026 09:38:49 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.54.220]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id E1D003F632; Tue, 3 Feb 2026 09:38:54 -0800 (PST) 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" X-Inumbo-ID: 36fa34b3-0127-11f1-9ccf-f158ae23cfc8 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Jens Wiklander , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 11/12] xen/arm: ffa: Add MEM_SHARE page diagnostics Date: Tue, 3 Feb 2026 18:38:06 +0100 Message-ID: <94e10f14d499d7e584fb0fbdd28d0288bb5831bd.1770115302.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.51.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1770140867576158500 Content-Type: text/plain; charset="utf-8" MEM_SHARE failures in get_shm_pages() are silent, which makes malformed ranges and page mapping failures hard to diagnose. Add debug logging for page validation failures: - descriptor validation failures (unaligned, range short/overflow) - per-page mapping failures (unmapped GFN, wrong p2m type) - address overflow detection in range walks Ratelimit temporary reclaim failures and log permanent reclaim failures as errors. No functional changes. Signed-off-by: Bertrand Marquis --- xen/arch/arm/tee/ffa_shm.c | 73 ++++++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 10 deletions(-) diff --git a/xen/arch/arm/tee/ffa_shm.c b/xen/arch/arm/tee/ffa_shm.c index 905a64e3db01..89161753e922 100644 --- a/xen/arch/arm/tee/ffa_shm.c +++ b/xen/arch/arm/tee/ffa_shm.c @@ -169,6 +169,12 @@ static int32_t get_shm_pages(struct domain *d, struct = ffa_shm_mem *shm, uint64_t addr; uint64_t page_count; uint64_t gaddr; + int32_t ret =3D FFA_RET_OK; + const char *reason =3D NULL; + unsigned int bad_rg =3D 0; + unsigned int bad_pg =3D 0; + unsigned long bad_addr =3D 0; + p2m_type_t bad_t =3D p2m_invalid; =20 for ( n =3D 0; n < range_count; n++ ) { @@ -176,34 +182,78 @@ static int32_t get_shm_pages(struct domain *d, struct= ffa_shm_mem *shm, addr =3D ACCESS_ONCE(range[n].address); =20 if ( !IS_ALIGNED(addr, FFA_PAGE_SIZE) ) - return FFA_RET_INVALID_PARAMETERS; + { + ret =3D FFA_RET_INVALID_PARAMETERS; + reason =3D "unaligned"; + bad_rg =3D n; + bad_addr =3D (unsigned long)addr; + goto out; + } =20 for ( m =3D 0; m < page_count; m++ ) { if ( pg_idx >=3D shm->page_count ) - return FFA_RET_INVALID_PARAMETERS; + { + ret =3D FFA_RET_INVALID_PARAMETERS; + reason =3D "range overflow"; + bad_rg =3D n; + bad_pg =3D m; + goto out; + } =20 if ( !ffa_safe_addr_add(addr, m) ) - return FFA_RET_INVALID_PARAMETERS; + { + ret =3D FFA_RET_INVALID_PARAMETERS; + reason =3D "addr overflow"; + bad_rg =3D n; + bad_pg =3D m; + bad_addr =3D (unsigned long)addr; + goto out; + } =20 gaddr =3D addr + m * FFA_PAGE_SIZE; gfn =3D gaddr_to_gfn(gaddr); shm->pages[pg_idx] =3D get_page_from_gfn(d, gfn_x(gfn), &t, P2M_ALLOC); if ( !shm->pages[pg_idx] ) - return FFA_RET_DENIED; + { + ret =3D FFA_RET_DENIED; + reason =3D "gfn unmapped"; + bad_rg =3D n; + bad_pg =3D m; + bad_addr =3D (unsigned long)gaddr; + goto out; + } /* Only normal RW RAM for now */ if ( t !=3D p2m_ram_rw ) - return FFA_RET_DENIED; + { + ret =3D FFA_RET_DENIED; + reason =3D "p2m type"; + bad_rg =3D n; + bad_pg =3D m; + bad_addr =3D (unsigned long)gaddr; + bad_t =3D t; + goto out; + } pg_idx++; } } =20 /* The ranges must add up */ if ( pg_idx < shm->page_count ) - return FFA_RET_INVALID_PARAMETERS; + { + ret =3D FFA_RET_INVALID_PARAMETERS; + reason =3D "range short"; + bad_pg =3D pg_idx; + goto out; + } =20 - return FFA_RET_OK; +out: + if ( ret ) + gdprintk(XENLOG_DEBUG, + "ffa: mem share pages invalid: %s rg %u pg %u addr %#lx p= 2m %u\n", + reason ? reason : "unknown", bad_rg, bad_pg, bad_addr, ba= d_t); + return ret; } =20 static void put_shm_pages(struct ffa_shm_mem *shm) @@ -759,8 +809,10 @@ bool ffa_shm_domain_destroy(struct domain *d) * A temporary error that may get resolved a bit later, it's * worth retrying. */ - printk(XENLOG_G_INFO "%pd: ffa: Failed to reclaim handle %#lx = : %d\n", - d, shm->handle, res); + if ( printk_ratelimit() ) + printk(XENLOG_G_WARNING + "%pd: ffa: Failed to reclaim handle %#lx : %d\n", + d, shm->handle, res); break; /* We will retry later */ default: /* @@ -772,7 +824,8 @@ bool ffa_shm_domain_destroy(struct domain *d) * FFA_RET_NO_MEMORY might be a temporary error as it it could * succeed if retried later, but treat it as permanent for now. */ - printk(XENLOG_G_INFO "%pd: ffa: Permanent failure to reclaim h= andle %#lx : %d\n", + printk(XENLOG_G_ERR + "%pd: ffa: Permanent failure to reclaim handle %#lx : %= d\n", d, shm->handle, res); =20 /* --=20 2.50.1 (Apple Git-155) From nobody Sat Feb 7 07:31:33 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; 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=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1770140872585913.3416677155207; Tue, 3 Feb 2026 09:47:52 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1219623.1528512 (Exim 4.92) (envelope-from ) id 1vnKUs-0006wL-Vf; Tue, 03 Feb 2026 17:47:30 +0000 Received: by outflank-mailman (output) from mailman id 1219623.1528512; Tue, 03 Feb 2026 17:47:30 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKUs-0006w6-RC; Tue, 03 Feb 2026 17:47:30 +0000 Received: by outflank-mailman (input) for mailman id 1219623; Tue, 03 Feb 2026 17:47:29 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vnKMg-0000Zt-RN for xen-devel@lists.xenproject.org; Tue, 03 Feb 2026 17:39:02 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 37c46894-0127-11f1-9ccf-f158ae23cfc8; Tue, 03 Feb 2026 18:38:57 +0100 (CET) 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 DB4B6150C; Tue, 3 Feb 2026 09:38:50 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.54.220]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 399083F632; Tue, 3 Feb 2026 09:38:56 -0800 (PST) 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" X-Inumbo-ID: 37c46894-0127-11f1-9ccf-f158ae23cfc8 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Jens Wiklander , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 12/12] xen/arm: ffa: Add message parameter diagnostics Date: Tue, 3 Feb 2026 18:38:07 +0100 Message-ID: <209e5474e236737dd13e0f7ff8120b05cdb7eabe.1770115302.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.51.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1770140880880158500 Content-Type: text/plain; charset="utf-8" MSG_SEND2 and direct request validation failures are silent, making it hard to diagnose invalid IDs, oversized messages, or unsupported destination types. Add debug logs for parameter validation failures: - invalid endpoint IDs - oversized messages - unsupported destination types - invalid sender/receiver combinations - ratelimit MSG_SEND2 busy failures to avoid log flooding No functional changes. Signed-off-by: Bertrand Marquis --- xen/arch/arm/tee/ffa_msg.c | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/xen/arch/arm/tee/ffa_msg.c b/xen/arch/arm/tee/ffa_msg.c index 928f269f6c3a..cc273c9a8e80 100644 --- a/xen/arch/arm/tee/ffa_msg.c +++ b/xen/arch/arm/tee/ffa_msg.c @@ -4,6 +4,7 @@ */ =20 #include +#include #include #include =20 @@ -100,6 +101,7 @@ void ffa_handle_msg_send_direct_req(struct cpu_user_reg= s *regs, uint32_t fid) if ( !ffa_fw_supports_fid(fid) ) { ret =3D FFA_RET_NOT_SUPPORTED; + gdprintk(XENLOG_DEBUG, "ffa: direct req fid %#x not supported\n", = fid); goto out; } =20 @@ -108,6 +110,9 @@ void ffa_handle_msg_send_direct_req(struct cpu_user_reg= s *regs, uint32_t fid) (src_dst & GENMASK(15,0)) =3D=3D ffa_get_vm_id(d) ) { ret =3D FFA_RET_INVALID_PARAMETERS; + gdprintk(XENLOG_DEBUG, + "ffa: direct req invalid src/dst %#x\n", + (uint32_t)src_dst); goto out; } =20 @@ -115,6 +120,9 @@ void ffa_handle_msg_send_direct_req(struct cpu_user_reg= s *regs, uint32_t fid) if ( !FFA_ID_IS_SECURE(src_dst & GENMASK(15,0)) ) { ret =3D FFA_RET_NOT_SUPPORTED; + gdprintk(XENLOG_DEBUG, + "ffa: direct req to non-secure dst %#x\n", + (uint32_t)(src_dst & GENMASK(15, 0))); goto out; } =20 @@ -166,7 +174,12 @@ static int32_t ffa_msg_send2_vm(uint16_t dst_id, const= void *src_buf, /* This is also checking that dest is not src */ ret =3D ffa_endpoint_domain_lookup(dst_id, &dst_d, &dst_ctx); if ( ret ) + { + gdprintk(XENLOG_DEBUG, + "ffa: msg_send2 lookup failed: dst %#x ret %d\n", + dst_id, ret); return ret; + } =20 /* This also checks that destination has set a Rx buffer */ ret =3D ffa_rx_acquire(dst_ctx , &rx_buf, &rx_size); @@ -199,6 +212,12 @@ static int32_t ffa_msg_send2_vm(uint16_t dst_id, const= void *src_buf, /* receiver rx buffer will be released by the receiver*/ =20 out_unlock: + if ( ret ) + { + if ( ret !=3D FFA_RET_BUSY || printk_ratelimit() ) + gdprintk(XENLOG_DEBUG, "ffa: msg_send2 to %#x failed: %d\n", + dst_id, ret); + } rcu_unlock_domain(dst_d); if ( !ret ) ffa_raise_rx_buffer_full(dst_d); @@ -226,7 +245,11 @@ int32_t ffa_handle_msg_send2(struct cpu_user_regs *reg= s) =20 ret =3D ffa_tx_acquire(src_ctx, &tx_buf, &tx_size); if ( ret !=3D FFA_RET_OK ) + { + gdprintk(XENLOG_DEBUG, + "ffa: msg_send2 TX acquire failed: %d\n", ret); return ret; + } =20 /* create a copy of the message header */ memcpy(&src_msg, tx_buf, sizeof(src_msg)); @@ -238,6 +261,9 @@ int32_t ffa_handle_msg_send2(struct cpu_user_regs *regs) dst_id =3D=3D ffa_get_vm_id(src_d) ) { ret =3D FFA_RET_INVALID_PARAMETERS; + gdprintk(XENLOG_DEBUG, + "ffa: msg_send2 invalid src/dst src %#x dst %#x\n", + src_id, dst_id); goto out; } =20 @@ -246,6 +272,9 @@ int32_t ffa_handle_msg_send2(struct cpu_user_regs *regs) if (src_msg.msg_offset < sizeof(struct ffa_part_msg_rxtx_1_1)) { ret =3D FFA_RET_INVALID_PARAMETERS; + gdprintk(XENLOG_DEBUG, + "ffa: msg_send2 invalid msg_offset %u (v1.1)\n", + src_msg.msg_offset); goto out; } /* Set uuid to Nil UUID for v1.1 guests */ @@ -255,6 +284,9 @@ int32_t ffa_handle_msg_send2(struct cpu_user_regs *regs) else if ( src_msg.msg_offset < sizeof(struct ffa_part_msg_rxtx_1_2) ) { ret =3D FFA_RET_INVALID_PARAMETERS; + gdprintk(XENLOG_DEBUG, + "ffa: msg_send2 invalid msg_offset %u (v1.2)\n", + src_msg.msg_offset); goto out; } =20 @@ -263,6 +295,9 @@ int32_t ffa_handle_msg_send2(struct cpu_user_regs *regs) src_msg.msg_size > (tx_size - src_msg.msg_offset) ) { ret =3D FFA_RET_INVALID_PARAMETERS; + gdprintk(XENLOG_DEBUG, + "ffa: msg_send2 invalid msg_size %u offset %u tx %zu\n", + src_msg.msg_size, src_msg.msg_offset, tx_size); goto out; } =20 @@ -272,6 +307,8 @@ int32_t ffa_handle_msg_send2(struct cpu_user_regs *regs) if ( !ffa_fw_supports_fid(FFA_MSG_SEND2) ) { ret =3D FFA_RET_NOT_SUPPORTED; + gdprintk(XENLOG_DEBUG, + "ffa: msg_send2 to SP not supported\n"); goto out; } /* @@ -288,6 +325,8 @@ int32_t ffa_handle_msg_send2(struct cpu_user_regs *regs) =20 ret =3D ffa_simple_call(FFA_MSG_SEND2, ((uint32_t)ffa_get_vm_id(src_d)) << 16, 0, 0= , 0); + if ( ret ) + gdprintk(XENLOG_DEBUG, "ffa: msg_send2 to SP failed: %d\n", re= t); } else if ( IS_ENABLED(CONFIG_FFA_VM_TO_VM) ) { @@ -295,7 +334,11 @@ int32_t ffa_handle_msg_send2(struct cpu_user_regs *reg= s) ret =3D ffa_msg_send2_vm(dst_id, tx_buf, &src_msg); } else + { ret =3D FFA_RET_INVALID_PARAMETERS; + gdprintk(XENLOG_DEBUG, + "ffa: msg_send2 to VM disabled (dst %#x)\n", dst_id); + } =20 out: ffa_tx_release(src_ctx); @@ -311,6 +354,7 @@ void ffa_handle_run(struct cpu_user_regs *regs, uint32_= t fid) if ( !ffa_fw_supports_fid(fid) ) { ret =3D FFA_RET_NOT_SUPPORTED; + gdprintk(XENLOG_DEBUG, "ffa: run fid %#x not supported\n", fid); goto out; } =20 @@ -322,6 +366,7 @@ void ffa_handle_run(struct cpu_user_regs *regs, uint32_= t fid) if ( !FFA_ID_IS_SECURE(dst >> 16) ) { ret =3D FFA_RET_NOT_SUPPORTED; + gdprintk(XENLOG_DEBUG, "ffa: run to non-secure dst %#x\n", dst); goto out; } =20 --=20 2.50.1 (Apple Git-155)