From nobody Sat Dec 13 06:18:05 2025 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 1764931098118349.5424719777502; Fri, 5 Dec 2025 02:38:18 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1178646.1502464 (Exim 4.92) (envelope-from ) id 1vRTCF-0008Bc-2H; Fri, 05 Dec 2025 10:37:55 +0000 Received: by outflank-mailman (output) from mailman id 1178646.1502464; Fri, 05 Dec 2025 10:37: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 1vRTCE-0008Au-SS; Fri, 05 Dec 2025 10:37:54 +0000 Received: by outflank-mailman (input) for mailman id 1178646; Fri, 05 Dec 2025 10:37: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 1vRTCD-0005Ju-T7 for xen-devel@lists.xenproject.org; Fri, 05 Dec 2025 10:37:53 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 734c913f-d1c6-11f0-980a-7dc792cee155; Fri, 05 Dec 2025 11:37: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 EBF9F1063; Fri, 5 Dec 2025 02:37:43 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.45.211]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 463BF3F86F; Fri, 5 Dec 2025 02:37: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: 734c913f-d1c6-11f0-980a-7dc792cee155 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v1 10/12] xen/arm: ffa: add v1.2 SEND2 header layout Date: Fri, 5 Dec 2025 11:36:43 +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: 1764931099938019200 Content-Type: text/plain; charset="utf-8" Teach the SEND2 path about the distinct FF-A v1.1 and v1.2 RX/TX header layouts so we can propagate the 128-bit UUIDs introduced in v1.2. VM-to-VM SEND2 calls now build the larger v1.2 header, zeroing the UUID fields for v1.1 senders, and the dispatcher validates messages using the v1.1 header layout to keep legacy guests working. While there, make the code more robust by checking that the send is not trying to send a message to himself. Signed-off-by: Bertrand Marquis Reviewed-by: Jens Wiklander --- Changes in v1: - Mention self send check in commit message - check header size depending on sender FF-A version and make sure 1.2 has enough space for 1.2 header - Simplify the code by setting uuid field of the header to Nil-UUID when testing the caller version and remove the need to pass the context to the send2_vm function - Use ACCESS_ONCE when reading sender ffa version --- xen/arch/arm/tee/ffa_msg.c | 58 ++++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/xen/arch/arm/tee/ffa_msg.c b/xen/arch/arm/tee/ffa_msg.c index 5a4cb1bb8295..c3552a3ae36d 100644 --- a/xen/arch/arm/tee/ffa_msg.c +++ b/xen/arch/arm/tee/ffa_msg.c @@ -13,7 +13,7 @@ #include "ffa_private.h" =20 /* Encoding of partition message in RX/TX buffer */ -struct ffa_part_msg_rxtx { +struct ffa_part_msg_rxtx_1_1 { uint32_t flags; uint32_t reserved; uint32_t msg_offset; @@ -21,6 +21,16 @@ struct ffa_part_msg_rxtx { uint32_t msg_size; }; =20 +struct ffa_part_msg_rxtx_1_2 { + uint32_t flags; + uint32_t reserved; + uint32_t msg_offset; + uint32_t send_recv_id; + uint32_t msg_size; + uint32_t reserved2; + uint64_t uuid[2]; +}; + static void ffa_finish_direct_req_run(struct cpu_user_regs *regs, struct arm_smccc_1_2_regs *req) { @@ -105,11 +115,11 @@ out: } =20 static int32_t ffa_msg_send2_vm(uint16_t dst_id, const void *src_buf, - struct ffa_part_msg_rxtx *src_msg) + struct ffa_part_msg_rxtx_1_2 *src_msg) { struct domain *dst_d; struct ffa_ctx *dst_ctx; - struct ffa_part_msg_rxtx *dst_msg; + struct ffa_part_msg_rxtx_1_2 *dst_msg; void *rx_buf; size_t rx_size; int err; @@ -143,7 +153,7 @@ static int32_t ffa_msg_send2_vm(uint16_t dst_id, const = void *src_buf, goto out_unlock; =20 /* we need to have enough space in the destination buffer */ - if ( (rx_size - sizeof(struct ffa_part_msg_rxtx)) < src_msg->msg_size ) + if ( (rx_size - sizeof(struct ffa_part_msg_rxtx_1_2)) < src_msg->msg_s= ize ) { ret =3D FFA_RET_NO_MEMORY; ffa_rx_release(dst_ctx); @@ -155,11 +165,14 @@ static int32_t ffa_msg_send2_vm(uint16_t dst_id, cons= t void *src_buf, /* prepare destination header */ dst_msg->flags =3D 0; dst_msg->reserved =3D 0; - dst_msg->msg_offset =3D sizeof(struct ffa_part_msg_rxtx); + dst_msg->msg_offset =3D sizeof(struct ffa_part_msg_rxtx_1_2); dst_msg->send_recv_id =3D src_msg->send_recv_id; dst_msg->msg_size =3D src_msg->msg_size; + dst_msg->reserved2 =3D 0; + dst_msg->uuid[0] =3D src_msg->uuid[0]; + dst_msg->uuid[1] =3D src_msg->uuid[1]; =20 - memcpy(rx_buf + sizeof(struct ffa_part_msg_rxtx), + memcpy(rx_buf + sizeof(struct ffa_part_msg_rxtx_1_2), src_buf + src_msg->msg_offset, src_msg->msg_size); =20 /* receiver rx buffer will be released by the receiver*/ @@ -178,11 +191,17 @@ int32_t ffa_handle_msg_send2(struct cpu_user_regs *re= gs) struct ffa_ctx *src_ctx =3D src_d->arch.tee; const void *tx_buf; size_t tx_size; - struct ffa_part_msg_rxtx src_msg; + /* + * src_msg is interpreted as v1.2 header, but: + * - for v1.1 guests, uuid[] is ignored and may contain payload bytes + * - for v1.2 guests, uuid[] carries the FF-A v1.2 UUID fields + */ + struct ffa_part_msg_rxtx_1_2 src_msg; uint16_t dst_id, src_id; int32_t ret; =20 - BUILD_BUG_ON(sizeof(struct ffa_part_msg_rxtx) >=3D FFA_PAGE_SIZE); + BUILD_BUG_ON(sizeof(struct ffa_part_msg_rxtx_1_1) >=3D FFA_PAGE_SIZE); + BUILD_BUG_ON(sizeof(struct ffa_part_msg_rxtx_1_2) >=3D FFA_PAGE_SIZE); =20 ret =3D ffa_tx_acquire(src_ctx, &tx_buf, &tx_size); if ( ret !=3D FFA_RET_OK ) @@ -194,15 +213,32 @@ int32_t ffa_handle_msg_send2(struct cpu_user_regs *re= gs) src_id =3D src_msg.send_recv_id >> 16; dst_id =3D src_msg.send_recv_id & GENMASK(15,0); =20 - if ( src_id !=3D ffa_get_vm_id(src_d) ) + if ( src_id !=3D ffa_get_vm_id(src_d) || + dst_id =3D=3D ffa_get_vm_id(src_d) ) + { + ret =3D FFA_RET_INVALID_PARAMETERS; + goto out; + } + + if ( ACCESS_ONCE(src_ctx->guest_vers) < FFA_VERSION_1_2 ) + { + if (src_msg.msg_offset < sizeof(struct ffa_part_msg_rxtx_1_1)) + { + ret =3D FFA_RET_INVALID_PARAMETERS; + goto out; + } + /* Set uuid to Nil UUID for v1.1 guests */ + src_msg.uuid[0] =3D 0; + src_msg.uuid[1] =3D 0; + } + else if ( src_msg.msg_offset < sizeof(struct ffa_part_msg_rxtx_1_2) ) { ret =3D FFA_RET_INVALID_PARAMETERS; goto out; } =20 /* check source message fits in buffer */ - if ( src_msg.msg_offset < sizeof(struct ffa_part_msg_rxtx) || - src_msg.msg_size =3D=3D 0 || src_msg.msg_offset > tx_size || + if ( src_msg.msg_size =3D=3D 0 || src_msg.msg_offset > tx_size || src_msg.msg_size > (tx_size - src_msg.msg_offset) ) { ret =3D FFA_RET_INVALID_PARAMETERS; --=20 2.51.2