From patchwork Wed Nov 27 16:07:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13887172 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6E91AD6ACF1 for ; Wed, 27 Nov 2024 16:08:22 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.844893.1260418 (Exim 4.92) (envelope-from ) id 1tGKaQ-0003ZL-5v; Wed, 27 Nov 2024 16:08:18 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 844893.1260418; Wed, 27 Nov 2024 16:08:18 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tGKaQ-0003ZE-3E; Wed, 27 Nov 2024 16:08:18 +0000 Received: by outflank-mailman (input) for mailman id 844893; Wed, 27 Nov 2024 16:08:17 +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 1tGKaP-00034d-7G for xen-devel@lists.xenproject.org; Wed, 27 Nov 2024 16:08:17 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id cdfb3c6a-acd9-11ef-99a3-01e77a169b0f; Wed, 27 Nov 2024 17:08:13 +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 4C8F01477; Wed, 27 Nov 2024 08:08:43 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.58.181]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id D98AA3F5A1; Wed, 27 Nov 2024 08:08:11 -0800 (PST) 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: cdfb3c6a-acd9-11ef-99a3-01e77a169b0f X-Custom-Connection: eyJyZW1vdGVpcCI6IjIxNy4xNDAuMTEwLjE3MiIsImhlbG8iOiJmb3NzLmFybS5jb20ifQ== X-Custom-Transaction: eyJpZCI6ImNkZmIzYzZhLWFjZDktMTFlZi05OWEzLTAxZTc3YTE2OWIwZiIsInRzIjoxNzMyNzIzNjk0LjA4MjUyNiwic2VuZGVyIjoiYmVydHJhbmQubWFycXVpc0Bhcm0uY29tIiwicmVjaXBpZW50IjoieGVuLWRldmVsQGxpc3RzLnhlbnByb2plY3Qub3JnIn0= From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v3 01/10] xen/arm: ffa: Rework firmware discovery Date: Wed, 27 Nov 2024 17:07:33 +0100 Message-ID: <3fcc536cd2e13d0421839fc6890daeda71cfac44.1732702210.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: References: MIME-Version: 1.0 Rework firmware discovery during probe: - move prints into the probe - rename ffa_version to ffa_fw_version as the variable identifies the version of the firmware and not the one we support - add error prints when allocation fail during probe No functional changes. Signed-off-by: Bertrand Marquis --- Changes in v3: - Revert spurious change assigning major_vers - Remove error print in ffa_rxtx_init as we have already a print in the main init function Changes in v2: - Fix error message when we fail to retrieve ffa_version - Move back printing the firmware version before checking supported features - Use Warning instead of Info to inform user that FF-A is not supported in firmware. --- xen/arch/arm/tee/ffa.c | 41 ++++++++++++++++++++++--------------- xen/arch/arm/tee/ffa_rxtx.c | 4 +--- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index 022089278e1c..5a7f297ca5c6 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -71,8 +71,8 @@ #include "ffa_private.h" -/* Negotiated FF-A version to use with the SPMC */ -static uint32_t __ro_after_init ffa_version; +/* Negotiated FF-A version to use with the SPMC, 0 if not there or supported */ +static uint32_t __ro_after_init ffa_fw_version; /* @@ -105,10 +105,7 @@ static bool ffa_get_version(uint32_t *vers) arm_smccc_1_2_smc(&arg, &resp); if ( resp.a0 == FFA_RET_NOT_SUPPORTED ) - { - gprintk(XENLOG_ERR, "ffa: FFA_VERSION returned not supported\n"); return false; - } *vers = resp.a0; @@ -372,7 +369,7 @@ static int ffa_domain_init(struct domain *d) struct ffa_ctx *ctx; int ret; - if ( !ffa_version ) + if ( !ffa_fw_version ) return -ENODEV; /* * We can't use that last possible domain ID or ffa_get_vm_id() would @@ -505,6 +502,9 @@ static bool ffa_probe(void) */ BUILD_BUG_ON(PAGE_SIZE != FFA_PAGE_SIZE); + printk(XENLOG_INFO "ARM FF-A Mediator version %u.%u\n", + FFA_MY_VERSION_MAJOR, FFA_MY_VERSION_MINOR); + /* * psci_init_smccc() updates this value with what's reported by EL-3 * or secure world. @@ -514,22 +514,23 @@ static bool ffa_probe(void) printk(XENLOG_ERR "ffa: unsupported SMCCC version %#x (need at least %#x)\n", smccc_ver, ARM_SMCCC_VERSION_1_2); - return false; + goto err_no_fw; } if ( !ffa_get_version(&vers) ) - return false; + { + gprintk(XENLOG_ERR, "Cannot retrieve the FFA version\n"); + goto err_no_fw; + } if ( vers < FFA_MIN_SPMC_VERSION || vers > FFA_MY_VERSION ) { printk(XENLOG_ERR "ffa: Incompatible version %#x found\n", vers); - return false; + goto err_no_fw; } major_vers = (vers >> FFA_VERSION_MAJOR_SHIFT) & FFA_VERSION_MAJOR_MASK; minor_vers = vers & FFA_VERSION_MINOR_MASK; - printk(XENLOG_INFO "ARM FF-A Mediator version %u.%u\n", - FFA_MY_VERSION_MAJOR, FFA_MY_VERSION_MINOR); printk(XENLOG_INFO "ARM FF-A Firmware version %u.%u\n", major_vers, minor_vers); @@ -546,12 +547,18 @@ static bool ffa_probe(void) !check_mandatory_feature(FFA_MEM_SHARE_32) || !check_mandatory_feature(FFA_MEM_RECLAIM) || !check_mandatory_feature(FFA_MSG_SEND_DIRECT_REQ_32) ) - return false; + { + printk(XENLOG_ERR "ffa: Mandatory feature not supported by fw\n"); + goto err_no_fw; + } - if ( !ffa_rxtx_init() ) - return false; + ffa_fw_version = vers; - ffa_version = vers; + if ( !ffa_rxtx_init() ) + { + printk(XENLOG_ERR "ffa: Error during RXTX buffer init\n"); + goto err_no_fw; + } if ( !ffa_partinfo_init() ) goto err_rxtx_destroy; @@ -564,7 +571,9 @@ static bool ffa_probe(void) err_rxtx_destroy: ffa_rxtx_destroy(); - ffa_version = 0; +err_no_fw: + ffa_fw_version = 0; + printk(XENLOG_WARNING "ARM FF-A No firmware support\n"); return false; } diff --git a/xen/arch/arm/tee/ffa_rxtx.c b/xen/arch/arm/tee/ffa_rxtx.c index 661764052e67..c8bc516a19be 100644 --- a/xen/arch/arm/tee/ffa_rxtx.c +++ b/xen/arch/arm/tee/ffa_rxtx.c @@ -203,10 +203,8 @@ bool ffa_rxtx_init(void) e = ffa_rxtx_map(__pa(ffa_tx), __pa(ffa_rx), FFA_RXTX_PAGE_COUNT); if ( e ) - { - printk(XENLOG_ERR "ffa: Failed to map rxtx: error %d\n", e); goto err; - } + return true; err: From patchwork Wed Nov 27 16:07:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13887173 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C43E2D6ACEF for ; Wed, 27 Nov 2024 16:08:29 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.844895.1260428 (Exim 4.92) (envelope-from ) id 1tGKaS-0003q2-D6; Wed, 27 Nov 2024 16:08:20 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 844895.1260428; Wed, 27 Nov 2024 16:08:20 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tGKaS-0003pw-9w; Wed, 27 Nov 2024 16:08:20 +0000 Received: by outflank-mailman (input) for mailman id 844895; Wed, 27 Nov 2024 16:08:19 +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 1tGKaQ-00034d-Vk for xen-devel@lists.xenproject.org; Wed, 27 Nov 2024 16:08:18 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id cf12dd55-acd9-11ef-99a3-01e77a169b0f; Wed, 27 Nov 2024 17:08:15 +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 0B1C6150C; Wed, 27 Nov 2024 08:08:45 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.58.181]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9B9A63F5A1; Wed, 27 Nov 2024 08:08:13 -0800 (PST) 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: cf12dd55-acd9-11ef-99a3-01e77a169b0f X-Custom-Connection: eyJyZW1vdGVpcCI6IjIxNy4xNDAuMTEwLjE3MiIsImhlbG8iOiJmb3NzLmFybS5jb20ifQ== X-Custom-Transaction: eyJpZCI6ImNmMTJkZDU1LWFjZDktMTFlZi05OWEzLTAxZTc3YTE2OWIwZiIsInRzIjoxNzMyNzIzNjk1Ljk2MDg0Nywic2VuZGVyIjoiYmVydHJhbmQubWFycXVpc0Bhcm0uY29tIiwicmVjaXBpZW50IjoieGVuLWRldmVsQGxpc3RzLnhlbnByb2plY3Qub3JnIn0= From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v3 02/10] xen/arm: ffa: Rework feature discovery Date: Wed, 27 Nov 2024 17:07:34 +0100 Message-ID: <244dc07cda4cdba30e305f62818141444223a4e4.1732702210.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: References: MIME-Version: 1.0 Store the list of ABI we need in a list and go through the list instead of having a list of conditions inside the code. No functional change. Signed-off-by: Bertrand Marquis --- Changes in v3: - remove const attribute for id in ffa_fw_abi struct Changes in v2: - Store a string version of ABI needed from firmware and print the name of the ABI not supported instead of the id - Restore comment with TODO which should not have been removed at this stage - fix to unsigned int the index in the loop on the array - use abi instead of feature in the names of the functions and variables as we are not checking features but abis --- xen/arch/arm/tee/ffa.c | 57 +++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index 5a7f297ca5c6..ade6aaa6fd1d 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -74,6 +74,31 @@ /* Negotiated FF-A version to use with the SPMC, 0 if not there or supported */ static uint32_t __ro_after_init ffa_fw_version; +struct ffa_fw_abi { + uint32_t id; + const char *name; +}; + +#define FW_ABI(abi) {abi,#abi} + +/* List of ABI we use from the firmware */ +static const struct ffa_fw_abi ffa_fw_abi_needed[] = { + FW_ABI(FFA_VERSION), + FW_ABI(FFA_FEATURES), + FW_ABI(FFA_NOTIFICATION_BITMAP_CREATE), + FW_ABI(FFA_NOTIFICATION_BITMAP_DESTROY), + FW_ABI(FFA_PARTITION_INFO_GET), + FW_ABI(FFA_NOTIFICATION_INFO_GET_64), + FW_ABI(FFA_NOTIFICATION_GET), + 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), + FW_ABI(FFA_MSG_SEND_DIRECT_REQ_64), +}; /* * Our rx/tx buffers shared with the SPMC. FFA_RXTX_PAGE_COUNT is the @@ -112,20 +137,9 @@ static bool ffa_get_version(uint32_t *vers) return true; } -static int32_t ffa_features(uint32_t id) -{ - return ffa_simple_call(FFA_FEATURES, id, 0, 0, 0); -} - -static bool check_mandatory_feature(uint32_t id) +static bool ffa_abi_supported(uint32_t id) { - int32_t ret = ffa_features(id); - - if ( ret ) - printk(XENLOG_ERR "ffa: mandatory feature id %#x missing: error %d\n", - id, ret); - - return !ret; + return !ffa_simple_call(FFA_FEATURES, id, 0, 0, 0); } static void handle_version(struct cpu_user_regs *regs) @@ -539,17 +553,14 @@ static bool ffa_probe(void) * TODO: Rework the code to allow domain to use a subset of the * features supported. */ - if ( !check_mandatory_feature(FFA_PARTITION_INFO_GET) || - !check_mandatory_feature(FFA_RX_RELEASE) || - !check_mandatory_feature(FFA_RXTX_MAP_64) || - !check_mandatory_feature(FFA_MEM_SHARE_64) || - !check_mandatory_feature(FFA_RXTX_UNMAP) || - !check_mandatory_feature(FFA_MEM_SHARE_32) || - !check_mandatory_feature(FFA_MEM_RECLAIM) || - !check_mandatory_feature(FFA_MSG_SEND_DIRECT_REQ_32) ) + for ( unsigned int i = 0; i < ARRAY_SIZE(ffa_fw_abi_needed); i++ ) { - printk(XENLOG_ERR "ffa: Mandatory feature not supported by fw\n"); - goto err_no_fw; + if ( !ffa_abi_supported(ffa_fw_abi_needed[i].id) ) + { + printk(XENLOG_INFO "ARM FF-A Firmware does not support %s\n", + ffa_fw_abi_needed[i].name); + goto err_no_fw; + } } ffa_fw_version = vers; From patchwork Wed Nov 27 16:07:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13887174 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1FB1DD6ACF2 for ; Wed, 27 Nov 2024 16:08:31 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.844896.1260438 (Exim 4.92) (envelope-from ) id 1tGKaU-00047o-Li; Wed, 27 Nov 2024 16:08:22 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 844896.1260438; Wed, 27 Nov 2024 16:08:22 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tGKaU-00047d-Hi; Wed, 27 Nov 2024 16:08:22 +0000 Received: by outflank-mailman (input) for mailman id 844896; Wed, 27 Nov 2024 16:08:20 +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 1tGKaS-00034d-U9 for xen-devel@lists.xenproject.org; Wed, 27 Nov 2024 16:08:20 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id d02bc6a7-acd9-11ef-99a3-01e77a169b0f; Wed, 27 Nov 2024 17:08:17 +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 E75C2244B; Wed, 27 Nov 2024 08:08:46 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.58.181]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 6A78D3F5A1; Wed, 27 Nov 2024 08:08:15 -0800 (PST) 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: d02bc6a7-acd9-11ef-99a3-01e77a169b0f X-Custom-Connection: eyJyZW1vdGVpcCI6IjIxNy4xNDAuMTEwLjE3MiIsImhlbG8iOiJmb3NzLmFybS5jb20ifQ== X-Custom-Transaction: eyJpZCI6ImQwMmJjNmE3LWFjZDktMTFlZi05OWEzLTAxZTc3YTE2OWIwZiIsInRzIjoxNzMyNzIzNjk3Ljc1NzMxMSwic2VuZGVyIjoiYmVydHJhbmQubWFycXVpc0Bhcm0uY29tIiwicmVjaXBpZW50IjoieGVuLWRldmVsQGxpc3RzLnhlbnByb2plY3Qub3JnIn0= From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v3 03/10] xen/arm: ffa: Fix version negotiation Date: Wed, 27 Nov 2024 17:07:35 +0100 Message-ID: <47944bb5ea18a7c7aa968534c7e28c26f2cada12.1732702210.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: References: MIME-Version: 1.0 Fix FFA version negotiation with the firmware to follow the specification guidance more closely (see FF-A Specification Version 1.1 in chapter 13.2.1). When the firmware returns OK we can have several cases: - the version requested is accepted but the firmware supports a greater one in the same major. - the firmware supports a greater major version. It could still return OK even if the version requested is not accepted. Reject it. - the firmware supports a lower version. It will return OK and give that version. Check if we support it and use it or reject it if we do not. Adapt the code to: - reject any version lower than the one we support or not with the same major version - use the version returned if in our supported range (currently 1.1 only) - use 1.1 if the version returned is greater. Also adapt the handling of version requests from VM: - use our version if same major but greater minor is requested - use requested version if same major but lower minor is requested - do not use if incompatible major is requested - always return our version without error to the requester [1] https://developer.arm.com/documentation/den0077/e/ Signed-off-by: Bertrand Marquis Reviewed-by: Jens Wiklander --- Changes in v3: - add Jens R-b Changes in v2: - add link in commit message and code to the version and chapter of the spec. - fix comment coding style - introduce macros to get the major and minor of a version - add BUILD_BUG_ON to validate that the SPMC version we want is compatible with our own version - rework version testing and selecting to be clearer by discarding different major or version lower than what we want and then selecting based on the minor version. - fix get_version handling to be more generic --- xen/arch/arm/tee/ffa.c | 53 +++++++++++++++++++++++++--------- xen/arch/arm/tee/ffa_private.h | 3 ++ 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index ade6aaa6fd1d..c5dcb4fe240c 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -148,13 +148,20 @@ static void handle_version(struct cpu_user_regs *regs) struct ffa_ctx *ctx = d->arch.tee; uint32_t vers = get_user_reg(regs, 1); - if ( vers < FFA_VERSION_1_1 ) - vers = FFA_VERSION_1_0; - else - vers = FFA_VERSION_1_1; - - ctx->guest_vers = vers; - ffa_set_regs(regs, vers, 0, 0, 0, 0, 0, 0, 0); + /* + * Guest will use the version it requested if it is our major and minor + * lower or equals to ours. If the minor is greater, our version will be + * used. + * In any case return our version to the caller. + */ + if ( FFA_VERSION_MAJOR(vers) == FFA_MY_VERSION_MAJOR ) + { + if ( FFA_VERSION_MINOR(vers) > FFA_MY_VERSION_MINOR ) + ctx->guest_vers = FFA_MY_VERSION; + else + ctx->guest_vers = vers; + } + ffa_set_regs(regs, FFA_MY_VERSION, 0, 0, 0, 0, 0, 0, 0); } static void handle_msg_send_direct_req(struct cpu_user_regs *regs, uint32_t fid) @@ -537,17 +544,39 @@ static bool ffa_probe(void) goto err_no_fw; } - if ( vers < FFA_MIN_SPMC_VERSION || vers > FFA_MY_VERSION ) + /* Some sanity check in case we update the version we support */ + BUILD_BUG_ON(FFA_MIN_SPMC_VERSION > FFA_MY_VERSION); + BUILD_BUG_ON(FFA_VERSION_MAJOR(FFA_MIN_SPMC_VERSION) != + FFA_MY_VERSION_MAJOR); + + major_vers = FFA_VERSION_MAJOR(vers); + minor_vers = FFA_VERSION_MINOR(vers); + + if ( major_vers != FFA_MY_VERSION_MAJOR || + minor_vers < FFA_VERSION_MINOR(FFA_MIN_SPMC_VERSION) ) { - printk(XENLOG_ERR "ffa: Incompatible version %#x found\n", vers); + printk(XENLOG_ERR "ffa: Incompatible firmware version %u.%u\n", + major_vers, minor_vers); goto err_no_fw; } - major_vers = (vers >> FFA_VERSION_MAJOR_SHIFT) & FFA_VERSION_MAJOR_MASK; - minor_vers = vers & FFA_VERSION_MINOR_MASK; printk(XENLOG_INFO "ARM FF-A Firmware version %u.%u\n", major_vers, minor_vers); + /* + * If the call succeed and the version returned is higher or equal to + * the one Xen requested, the version requested by Xen will be the one + * used. If the version returned is lower but compatible with Xen, Xen + * will use that version instead. + * A version with a different major or lower than the minimum version + * we support is rejected before. + * See https://developer.arm.com/documentation/den0077/e/ chapter 13.2.1 + */ + if ( minor_vers > FFA_MY_VERSION_MINOR ) + ffa_fw_version = FFA_MY_VERSION; + else + ffa_fw_version = vers; + /* * At the moment domains must support the same features used by Xen. * TODO: Rework the code to allow domain to use a subset of the @@ -563,8 +592,6 @@ static bool ffa_probe(void) } } - ffa_fw_version = vers; - if ( !ffa_rxtx_init() ) { printk(XENLOG_ERR "ffa: Error during RXTX buffer init\n"); diff --git a/xen/arch/arm/tee/ffa_private.h b/xen/arch/arm/tee/ffa_private.h index 7c6b06f686fc..045d9c4a0b56 100644 --- a/xen/arch/arm/tee/ffa_private.h +++ b/xen/arch/arm/tee/ffa_private.h @@ -35,6 +35,9 @@ #define MAKE_FFA_VERSION(major, minor) \ ((((major) & FFA_VERSION_MAJOR_MASK) << FFA_VERSION_MAJOR_SHIFT) | \ ((minor) & FFA_VERSION_MINOR_MASK)) +#define FFA_VERSION_MAJOR(vers) (((vers) >> FFA_VERSION_MAJOR_SHIFT) & \ + FFA_VERSION_MAJOR_MASK) +#define FFA_VERSION_MINOR(vers) ((vers) & FFA_VERSION_MINOR_MASK) #define FFA_VERSION_1_0 MAKE_FFA_VERSION(1, 0) #define FFA_VERSION_1_1 MAKE_FFA_VERSION(1, 1) From patchwork Wed Nov 27 16:07:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13887175 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 98DCAD6ACF4 for ; Wed, 27 Nov 2024 16:08:31 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.844898.1260449 (Exim 4.92) (envelope-from ) id 1tGKaW-0004Qo-41; Wed, 27 Nov 2024 16:08:24 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 844898.1260449; Wed, 27 Nov 2024 16:08: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 1tGKaV-0004Qh-Up; Wed, 27 Nov 2024 16:08:23 +0000 Received: by outflank-mailman (input) for mailman id 844898; Wed, 27 Nov 2024 16:08:22 +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 1tGKaU-0002q2-Ox for xen-devel@lists.xenproject.org; Wed, 27 Nov 2024 16:08:22 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id d1d6b6ef-acd9-11ef-a0cd-8be0dac302b0; Wed, 27 Nov 2024 17:08:20 +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 C55C11477; Wed, 27 Nov 2024 08:08:49 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.58.181]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 5B51D3F5A1; Wed, 27 Nov 2024 08:08:17 -0800 (PST) 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: d1d6b6ef-acd9-11ef-a0cd-8be0dac302b0 X-Custom-Connection: eyJyZW1vdGVpcCI6IjIxNy4xNDAuMTEwLjE3MiIsImhlbG8iOiJmb3NzLmFybS5jb20ifQ== X-Custom-Transaction: eyJpZCI6ImQxZDZiNmVmLWFjZDktMTFlZi1hMGNkLThiZTBkYWMzMDJiMCIsInRzIjoxNzMyNzIzNzAwLjU4ODcwNCwic2VuZGVyIjoiYmVydHJhbmQubWFycXVpc0Bhcm0uY29tIiwicmVjaXBpZW50IjoieGVuLWRldmVsQGxpc3RzLnhlbnByb2plY3Qub3JnIn0= From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v3 04/10] xen/arm: ffa: Fine granular call support Date: Wed, 27 Nov 2024 17:07:36 +0100 Message-ID: <1b02c9c1df9ff2230e076f25398a5de876f98a51.1732702210.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: References: MIME-Version: 1.0 Create a bitmap to store which feature is supported or not by the firmware and use it to filter which calls are done to the firmware. While there reoder ABI definition by numbers to easily find the min and max ones. Signed-off-by: Bertrand Marquis Reviewed-by: Jens Wiklander --- Changes in v3: - add Jens R-b Changes in v2: - rename fw_feat to abi and macros to FFA_ABI to be coherent with the abi needed change done before - rework the macros to be simpler by directly defining MIN and MAX using only Function ids - check that requested function ids do not go over the bitmap size in ffa_fw_supports_fid - add an ASSERT to make sure that we do not try to set bits outside of the bitmap - turn off FF-A if there is not firmware support and adapt the commit message to reflect this - add a compile time check that FFA_ABI_MIN < FFA_ABI_MAX - remove spurious line removal - restore proper cleanup of rxtx init in case of error - reorder ABI by numbers --- xen/arch/arm/tee/ffa.c | 28 +++++++++++++++--------- xen/arch/arm/tee/ffa_notif.c | 7 ++++++ xen/arch/arm/tee/ffa_partinfo.c | 30 +++++++++++++++++++++++++- xen/arch/arm/tee/ffa_private.h | 38 ++++++++++++++++++++++++++++----- xen/arch/arm/tee/ffa_rxtx.c | 4 ++++ xen/arch/arm/tee/ffa_shm.c | 12 +++++++++++ 6 files changed, 103 insertions(+), 16 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index c5dcb4fe240c..1b0919041dc1 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -72,7 +72,10 @@ #include "ffa_private.h" /* Negotiated FF-A version to use with the SPMC, 0 if not there or supported */ -static uint32_t __ro_after_init ffa_fw_version; +uint32_t __ro_after_init ffa_fw_version; + +/* Features supported by the SPMC or secure world when present */ +DECLARE_BITMAP(ffa_fw_abi_supported, FFA_ABI_BITMAP_SIZE); struct ffa_fw_abi { uint32_t id; @@ -177,6 +180,13 @@ static void handle_msg_send_direct_req(struct cpu_user_regs *regs, uint32_t fid) else mask = GENMASK_ULL(31, 0); + if ( !ffa_fw_supports_fid(fid) ) + { + resp.a0 = FFA_ERROR; + resp.a2 = FFA_RET_NOT_SUPPORTED; + goto out; + } + src_dst = get_user_reg(regs, 1); if ( (src_dst >> 16) != ffa_get_vm_id(d) ) { @@ -577,19 +587,16 @@ static bool ffa_probe(void) else ffa_fw_version = vers; - /* - * At the moment domains must support the same features used by Xen. - * TODO: Rework the code to allow domain to use a subset of the - * features supported. - */ for ( unsigned int i = 0; i < ARRAY_SIZE(ffa_fw_abi_needed); i++ ) { - if ( !ffa_abi_supported(ffa_fw_abi_needed[i].id) ) - { + ASSERT(FFA_ABI_BITNUM(ffa_fw_abi_needed[i].id) < FFA_ABI_BITMAP_SIZE); + + if ( ffa_abi_supported(ffa_fw_abi_needed[i].id) ) + 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", ffa_fw_abi_needed[i].name); - goto err_no_fw; - } } if ( !ffa_rxtx_init() ) @@ -611,6 +618,7 @@ err_rxtx_destroy: ffa_rxtx_destroy(); err_no_fw: ffa_fw_version = 0; + bitmap_zero(ffa_fw_abi_supported, FFA_ABI_BITMAP_SIZE); printk(XENLOG_WARNING "ARM FF-A No firmware support\n"); return false; diff --git a/xen/arch/arm/tee/ffa_notif.c b/xen/arch/arm/tee/ffa_notif.c index 541e61d2f606..4b3e46318f4b 100644 --- a/xen/arch/arm/tee/ffa_notif.c +++ b/xen/arch/arm/tee/ffa_notif.c @@ -377,6 +377,13 @@ void ffa_notif_init(void) unsigned int irq; int ret; + /* Only enable fw notification if all ABIs we need are supported */ + if ( !(ffa_fw_supports_fid(FFA_NOTIFICATION_BITMAP_CREATE) && + ffa_fw_supports_fid(FFA_NOTIFICATION_BITMAP_DESTROY) && + ffa_fw_supports_fid(FFA_NOTIFICATION_GET) && + ffa_fw_supports_fid(FFA_NOTIFICATION_INFO_GET_64)) ) + return; + arm_smccc_1_2_smc(&arg, &resp); if ( resp.a0 != FFA_SUCCESS_32 ) return; diff --git a/xen/arch/arm/tee/ffa_partinfo.c b/xen/arch/arm/tee/ffa_partinfo.c index 93a03c6bc672..99c48f0e5c05 100644 --- a/xen/arch/arm/tee/ffa_partinfo.c +++ b/xen/arch/arm/tee/ffa_partinfo.c @@ -77,7 +77,15 @@ int32_t ffa_handle_partition_info_get(uint32_t w1, uint32_t w2, uint32_t w3, */ if ( w5 == FFA_PARTITION_INFO_GET_COUNT_FLAG && ctx->guest_vers == FFA_VERSION_1_1 ) - return ffa_partition_info_get(w1, w2, w3, w4, w5, count, fpi_size); + { + if ( ffa_fw_supports_fid(FFA_PARTITION_INFO_GET) ) + return ffa_partition_info_get(w1, w2, w3, w4, w5, count, fpi_size); + else + { + *count = 0; + return FFA_RET_OK; + } + } if ( w5 ) return FFA_RET_INVALID_PARAMETERS; @@ -87,6 +95,18 @@ int32_t ffa_handle_partition_info_get(uint32_t w1, uint32_t w2, uint32_t w3, if ( !spin_trylock(&ctx->rx_lock) ) return FFA_RET_BUSY; + if ( !ffa_fw_supports_fid(FFA_PARTITION_INFO_GET) ) + { + if ( ctx->guest_vers == FFA_VERSION_1_0 ) + *fpi_size = sizeof(struct ffa_partition_info_1_0); + else + *fpi_size = sizeof(struct ffa_partition_info_1_1); + + *count = 0; + ret = FFA_RET_OK; + goto out; + } + if ( !ctx->page_count || !ctx->rx_is_free ) goto out; spin_lock(&ffa_rx_buffer_lock); @@ -250,6 +270,11 @@ bool ffa_partinfo_init(void) uint32_t count; int e; + if ( !ffa_fw_supports_fid(FFA_PARTITION_INFO_GET) || + !ffa_fw_supports_fid(FFA_MSG_SEND_DIRECT_REQ_32) || + !ffa_rx || !ffa_tx ) + return false; + e = ffa_partition_info_get(0, 0, 0, 0, 0, &count, &fpi_size); if ( e ) { @@ -313,6 +338,9 @@ int ffa_partinfo_domain_init(struct domain *d) unsigned int n; int32_t res; + if ( !ffa_fw_supports_fid(FFA_MSG_SEND_DIRECT_REQ_32) ) + return 0; + ctx->vm_destroy_bitmap = xzalloc_array(unsigned long, count); if ( !ctx->vm_destroy_bitmap ) return -ENOMEM; diff --git a/xen/arch/arm/tee/ffa_private.h b/xen/arch/arm/tee/ffa_private.h index 045d9c4a0b56..85eb61c13464 100644 --- a/xen/arch/arm/tee/ffa_private.h +++ b/xen/arch/arm/tee/ffa_private.h @@ -14,6 +14,7 @@ #include #include #include +#include /* Error codes */ #define FFA_RET_OK 0 @@ -201,18 +202,17 @@ #define FFA_INTERRUPT 0x84000062U #define FFA_VERSION 0x84000063U #define FFA_FEATURES 0x84000064U -#define FFA_RX_ACQUIRE 0x84000084U #define FFA_RX_RELEASE 0x84000065U #define FFA_RXTX_MAP_32 0x84000066U #define FFA_RXTX_MAP_64 0xC4000066U #define FFA_RXTX_UNMAP 0x84000067U #define FFA_PARTITION_INFO_GET 0x84000068U #define FFA_ID_GET 0x84000069U -#define FFA_SPM_ID_GET 0x84000085U +#define FFA_MSG_POLL 0x8400006AU #define FFA_MSG_WAIT 0x8400006BU #define FFA_MSG_YIELD 0x8400006CU #define FFA_RUN 0x8400006DU -#define FFA_MSG_SEND2 0x84000086U +#define FFA_MSG_SEND 0x8400006EU #define FFA_MSG_SEND_DIRECT_REQ_32 0x8400006FU #define FFA_MSG_SEND_DIRECT_REQ_64 0xC400006FU #define FFA_MSG_SEND_DIRECT_RESP_32 0x84000070U @@ -230,8 +230,6 @@ #define FFA_MEM_RECLAIM 0x84000077U #define FFA_MEM_FRAG_RX 0x8400007AU #define FFA_MEM_FRAG_TX 0x8400007BU -#define FFA_MSG_SEND 0x8400006EU -#define FFA_MSG_POLL 0x8400006AU #define FFA_NOTIFICATION_BITMAP_CREATE 0x8400007DU #define FFA_NOTIFICATION_BITMAP_DESTROY 0x8400007EU #define FFA_NOTIFICATION_BIND 0x8400007FU @@ -240,6 +238,25 @@ #define FFA_NOTIFICATION_GET 0x84000082U #define FFA_NOTIFICATION_INFO_GET_32 0x84000083U #define FFA_NOTIFICATION_INFO_GET_64 0xC4000083U +#define FFA_RX_ACQUIRE 0x84000084U +#define FFA_SPM_ID_GET 0x84000085U +#define FFA_MSG_SEND2 0x84000086U + +/** + * Encoding of features supported or not by the fw in a bitmap: + * - Function IDs are going from 0x60 to 0xFF + * - A function can be supported in 32 and/or 64bit + * The bitmap has one bit for each function in 32 and 64 bit. + */ +#define FFA_ABI_ID(id) ((id) & ARM_SMCCC_FUNC_MASK) +#define FFA_ABI_CONV(id) (((id) >> ARM_SMCCC_CONV_SHIFT) & BIT(0,U)) + +#define FFA_ABI_MIN FFA_ABI_ID(FFA_ERROR) +#define FFA_ABI_MAX FFA_ABI_ID(FFA_MSG_SEND2) + +#define FFA_ABI_BITMAP_SIZE (2 * (FFA_ABI_MAX - FFA_ABI_MIN + 1)) +#define FFA_ABI_BITNUM(id) ((FFA_ABI_ID(id) - FFA_ABI_MIN) << 1 | \ + FFA_ABI_CONV(id)) struct ffa_ctx_notif { bool enabled; @@ -289,6 +306,8 @@ extern void *ffa_rx; extern void *ffa_tx; extern spinlock_t ffa_rx_buffer_lock; extern spinlock_t ffa_tx_buffer_lock; +extern uint32_t __ro_after_init ffa_fw_version; +extern DECLARE_BITMAP(ffa_fw_abi_supported, FFA_ABI_BITMAP_SIZE); bool ffa_shm_domain_destroy(struct domain *d); void ffa_handle_mem_share(struct cpu_user_regs *regs); @@ -401,4 +420,13 @@ static inline int32_t ffa_rx_release(void) return ffa_simple_call(FFA_RX_RELEASE, 0, 0, 0, 0); } +static inline bool ffa_fw_supports_fid(uint32_t fid) +{ + BUILD_BUG_ON(FFA_ABI_MIN > FFA_ABI_MAX); + + if ( FFA_ABI_BITNUM(fid) > FFA_ABI_BITMAP_SIZE) + return false; + return test_bit(FFA_ABI_BITNUM(fid), ffa_fw_abi_supported); +} + #endif /*__FFA_PRIVATE_H__*/ diff --git a/xen/arch/arm/tee/ffa_rxtx.c b/xen/arch/arm/tee/ffa_rxtx.c index c8bc516a19be..132a7982407b 100644 --- a/xen/arch/arm/tee/ffa_rxtx.c +++ b/xen/arch/arm/tee/ffa_rxtx.c @@ -193,6 +193,10 @@ bool ffa_rxtx_init(void) { int e; + /* Firmware not there or not supporting */ + if ( !ffa_fw_supports_fid(FFA_RXTX_MAP_64) ) + return false; + ffa_rx = alloc_xenheap_pages(get_order_from_pages(FFA_RXTX_PAGE_COUNT), 0); if ( !ffa_rx ) return false; diff --git a/xen/arch/arm/tee/ffa_shm.c b/xen/arch/arm/tee/ffa_shm.c index 370d83ec5cf8..efa5b67db8e1 100644 --- a/xen/arch/arm/tee/ffa_shm.c +++ b/xen/arch/arm/tee/ffa_shm.c @@ -149,6 +149,9 @@ static int32_t ffa_mem_share(uint32_t tot_len, uint32_t frag_len, static int32_t ffa_mem_reclaim(uint32_t handle_lo, uint32_t handle_hi, uint32_t flags) { + if ( !ffa_fw_supports_fid(FFA_MEM_RECLAIM) ) + return FFA_RET_NOT_SUPPORTED; + return ffa_simple_call(FFA_MEM_RECLAIM, handle_lo, handle_hi, flags, 0); } @@ -467,6 +470,12 @@ void ffa_handle_mem_share(struct cpu_user_regs *regs) uint32_t range_count; uint32_t region_offs; + if ( !ffa_fw_supports_fid(FFA_MEM_SHARE_64) ) + { + ret = FFA_RET_NOT_SUPPORTED; + goto out_set_ret; + } + /* * We're only accepting memory transaction descriptors via the rx/tx * buffer. @@ -621,6 +630,9 @@ int ffa_handle_mem_reclaim(uint64_t handle, uint32_t flags) register_t handle_lo; int ret; + if ( !ffa_fw_supports_fid(FFA_MEM_RECLAIM) ) + return FFA_RET_NOT_SUPPORTED; + spin_lock(&ctx->lock); shm = find_shm_mem(ctx, handle); if ( shm ) From patchwork Wed Nov 27 16:07:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13887176 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7A2A0D6ACF3 for ; Wed, 27 Nov 2024 16:08:31 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.844902.1260458 (Exim 4.92) (envelope-from ) id 1tGKaZ-0004nk-CQ; Wed, 27 Nov 2024 16:08:27 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 844902.1260458; Wed, 27 Nov 2024 16:08:27 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tGKaZ-0004nZ-80; Wed, 27 Nov 2024 16:08:27 +0000 Received: by outflank-mailman (input) for mailman id 844902; Wed, 27 Nov 2024 16:08:26 +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 1tGKaX-00034d-VR for xen-devel@lists.xenproject.org; Wed, 27 Nov 2024 16:08:25 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id d2fbc524-acd9-11ef-99a3-01e77a169b0f; Wed, 27 Nov 2024 17:08:22 +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 AC1A1150C; Wed, 27 Nov 2024 08:08:51 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.58.181]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 1FC243F5A1; Wed, 27 Nov 2024 08:08:19 -0800 (PST) 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: d2fbc524-acd9-11ef-99a3-01e77a169b0f X-Custom-Connection: eyJyZW1vdGVpcCI6IjIxNy4xNDAuMTEwLjE3MiIsImhlbG8iOiJmb3NzLmFybS5jb20ifQ== X-Custom-Transaction: eyJpZCI6ImQyZmJjNTI0LWFjZDktMTFlZi05OWEzLTAxZTc3YTE2OWIwZiIsInRzIjoxNzMyNzIzNzAyLjQ4NTYxMywic2VuZGVyIjoiYmVydHJhbmQubWFycXVpc0Bhcm0uY29tIiwicmVjaXBpZW50IjoieGVuLWRldmVsQGxpc3RzLnhlbnByb2plY3Qub3JnIn0= From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v3 05/10] xen/arm: ffa: Rework partition info get Date: Wed, 27 Nov 2024 17:07:37 +0100 Message-ID: <05750fccd29cd4527e7a8ee85455a0a1067f6983.1732702210.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: References: MIME-Version: 1.0 Rework the partition info get implementation to use the correct size of structure depending on the version of the protocol and simplifies the structure copy to use only memcpy and prevent recreating the structure each time. The goal here is to have an implementation that will be easier to maintain in the long term as the specification is only adding fields to structure with versions to simplify support of several protocol versions and as such an SPMC implementation in the future could use this and return a size higher than the one we expect. The patch is fixing the part_info_get function for this and the subscriber discovery on probe. No functional changes expected. Signed-off-by: Bertrand Marquis Reviewed-by: Jens Wiklander --- Changes in v3: - add Jens R-b Changes in v2: - rebase --- xen/arch/arm/tee/ffa.c | 13 +-- xen/arch/arm/tee/ffa_partinfo.c | 185 ++++++++++++++++++++------------ xen/arch/arm/tee/ffa_private.h | 4 +- 3 files changed, 118 insertions(+), 84 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index 1b0919041dc1..4b283a4de5d0 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -311,8 +311,6 @@ static bool ffa_handle_call(struct cpu_user_regs *regs) uint32_t fid = get_user_reg(regs, 0); struct domain *d = current->domain; struct ffa_ctx *ctx = d->arch.tee; - uint32_t fpi_size; - uint32_t count; int e; if ( !ctx ) @@ -338,16 +336,7 @@ static bool ffa_handle_call(struct cpu_user_regs *regs) e = ffa_handle_rxtx_unmap(); break; case FFA_PARTITION_INFO_GET: - e = ffa_handle_partition_info_get(get_user_reg(regs, 1), - get_user_reg(regs, 2), - get_user_reg(regs, 3), - get_user_reg(regs, 4), - get_user_reg(regs, 5), &count, - &fpi_size); - if ( e ) - ffa_set_regs_error(regs, e); - else - ffa_set_regs_success(regs, count, fpi_size); + ffa_handle_partition_info_get(regs); return true; case FFA_RX_RELEASE: e = ffa_handle_rx_release(); diff --git a/xen/arch/arm/tee/ffa_partinfo.c b/xen/arch/arm/tee/ffa_partinfo.c index 99c48f0e5c05..75a073d090e0 100644 --- a/xen/arch/arm/tee/ffa_partinfo.c +++ b/xen/arch/arm/tee/ffa_partinfo.c @@ -33,21 +33,24 @@ static uint16_t subscr_vm_created_count __read_mostly; static uint16_t *subscr_vm_destroyed __read_mostly; static uint16_t subscr_vm_destroyed_count __read_mostly; -static int32_t ffa_partition_info_get(uint32_t w1, uint32_t w2, uint32_t w3, - uint32_t w4, uint32_t w5, uint32_t *count, - uint32_t *fpi_size) +static int32_t ffa_partition_info_get(uint32_t *uuid, uint32_t flags, + uint32_t *count, uint32_t *fpi_size) { - const struct arm_smccc_1_2_regs arg = { + struct arm_smccc_1_2_regs arg = { .a0 = FFA_PARTITION_INFO_GET, - .a1 = w1, - .a2 = w2, - .a3 = w3, - .a4 = w4, - .a5 = w5, + .a5 = flags, }; struct arm_smccc_1_2_regs resp; uint32_t ret; + if ( uuid ) + { + arg.a1 = uuid[0]; + arg.a2 = uuid[1]; + arg.a3 = uuid[2]; + arg.a4 = uuid[3]; + } + arm_smccc_1_2_smc(&arg, &resp); ret = ffa_get_ret_code(&resp); @@ -60,13 +63,31 @@ static int32_t ffa_partition_info_get(uint32_t w1, uint32_t w2, uint32_t w3, return ret; } -int32_t ffa_handle_partition_info_get(uint32_t w1, uint32_t w2, uint32_t w3, - uint32_t w4, uint32_t w5, uint32_t *count, - uint32_t *fpi_size) +void ffa_handle_partition_info_get(struct cpu_user_regs *regs) { - int32_t ret = FFA_RET_DENIED; + int32_t ret; struct domain *d = current->domain; struct ffa_ctx *ctx = d->arch.tee; + uint32_t flags = get_user_reg(regs, 5); + uint32_t uuid[4] = { + get_user_reg(regs, 1), + get_user_reg(regs, 2), + get_user_reg(regs, 3), + get_user_reg(regs, 4), + }; + uint32_t src_size, dst_size; + void *dst_buf; + uint32_t ffa_sp_count = 0; + + /* + * If the guest is v1.0, he does not get back the entry size so we must + * use the v1.0 structure size in the destination buffer. + * Otherwise use the size of the highest version we support, here 1.1. + */ + if ( ctx->guest_vers == FFA_VERSION_1_0 ) + dst_size = sizeof(struct ffa_partition_info_1_0); + else + dst_size = sizeof(struct ffa_partition_info_1_1); /* * FF-A v1.0 has w5 MBZ while v1.1 allows @@ -75,90 +96,105 @@ int32_t ffa_handle_partition_info_get(uint32_t w1, uint32_t w2, uint32_t w3, * FFA_PARTITION_INFO_GET_COUNT is only using registers and not the * rxtx buffer so do the partition_info_get directly. */ - if ( w5 == FFA_PARTITION_INFO_GET_COUNT_FLAG && + if ( flags == FFA_PARTITION_INFO_GET_COUNT_FLAG && ctx->guest_vers == FFA_VERSION_1_1 ) { if ( ffa_fw_supports_fid(FFA_PARTITION_INFO_GET) ) - return ffa_partition_info_get(w1, w2, w3, w4, w5, count, fpi_size); + ret = ffa_partition_info_get(uuid, flags, &ffa_sp_count, + &src_size); else - { - *count = 0; - return FFA_RET_OK; - } - } - if ( w5 ) - return FFA_RET_INVALID_PARAMETERS; + ret = FFA_RET_OK; - if ( !ffa_rx ) - return FFA_RET_DENIED; + goto out; + } - if ( !spin_trylock(&ctx->rx_lock) ) - return FFA_RET_BUSY; + if ( flags ) + { + ret = FFA_RET_INVALID_PARAMETERS; + goto out; + } if ( !ffa_fw_supports_fid(FFA_PARTITION_INFO_GET) ) { - if ( ctx->guest_vers == FFA_VERSION_1_0 ) - *fpi_size = sizeof(struct ffa_partition_info_1_0); - else - *fpi_size = sizeof(struct ffa_partition_info_1_1); - - *count = 0; + /* Just give an empty partition list to the caller */ ret = FFA_RET_OK; goto out; } - if ( !ctx->page_count || !ctx->rx_is_free ) + if ( !spin_trylock(&ctx->rx_lock) ) + { + ret = FFA_RET_BUSY; goto out; + } + + dst_buf = ctx->rx; + + if ( !ffa_rx ) + { + ret = FFA_RET_DENIED; + goto out_rx_release; + } + + if ( !ctx->page_count || !ctx->rx_is_free ) + { + ret = FFA_RET_DENIED; + goto out_rx_release; + } + spin_lock(&ffa_rx_buffer_lock); - ret = ffa_partition_info_get(w1, w2, w3, w4, w5, count, fpi_size); + + ret = ffa_partition_info_get(uuid, 0, &ffa_sp_count, &src_size); + if ( ret ) goto out_rx_buf_unlock; + /* * ffa_partition_info_get() succeeded so we now own the RX buffer we * share with the SPMC. We must give it back using ffa_rx_release() * once we've copied the content. */ - if ( ctx->guest_vers == FFA_VERSION_1_0 ) + /* we cannot have a size smaller than 1.0 structure */ + if ( src_size < sizeof(struct ffa_partition_info_1_0) ) { - size_t n; - struct ffa_partition_info_1_1 *src = ffa_rx; - struct ffa_partition_info_1_0 *dst = ctx->rx; - - if ( ctx->page_count * FFA_PAGE_SIZE < *count * sizeof(*dst) ) - { - ret = FFA_RET_NO_MEMORY; - goto out_rx_release; - } + ret = FFA_RET_NOT_SUPPORTED; + goto out_rx_hyp_release; + } - for ( n = 0; n < *count; n++ ) - { - dst[n].id = src[n].id; - dst[n].execution_context = src[n].execution_context; - dst[n].partition_properties = src[n].partition_properties; - } + if ( ctx->page_count * FFA_PAGE_SIZE < ffa_sp_count * dst_size ) + { + ret = FFA_RET_NO_MEMORY; + goto out_rx_hyp_release; } - else + + if ( ffa_sp_count > 0 ) { - size_t sz = *count * *fpi_size; + uint32_t n; + void *src_buf = ffa_rx; - if ( ctx->page_count * FFA_PAGE_SIZE < sz ) + /* copy the secure partitions info */ + for ( n = 0; n < ffa_sp_count; n++ ) { - ret = FFA_RET_NO_MEMORY; - goto out_rx_release; + memcpy(dst_buf, src_buf, dst_size); + dst_buf += dst_size; + src_buf += src_size; } - - memcpy(ctx->rx, ffa_rx, sz); } + ctx->rx_is_free = false; -out_rx_release: + +out_rx_hyp_release: ffa_rx_release(); out_rx_buf_unlock: spin_unlock(&ffa_rx_buffer_lock); -out: +out_rx_release: spin_unlock(&ctx->rx_lock); - return ret; +out: + if ( ret ) + ffa_set_regs_error(regs, ret); + else + ffa_set_regs_success(regs, ffa_sp_count, dst_size); } static int32_t ffa_direct_req_send_vm(uint16_t sp_id, uint16_t vm_id, @@ -221,19 +257,28 @@ static void uninit_subscribers(void) XFREE(subscr_vm_destroyed); } -static bool init_subscribers(struct ffa_partition_info_1_1 *fpi, uint16_t count) +static bool init_subscribers(uint16_t count, uint32_t fpi_size) { uint16_t n; uint16_t c_pos; uint16_t d_pos; + struct ffa_partition_info_1_1 *fpi; + + if ( fpi_size < sizeof(struct ffa_partition_info_1_1) ) + { + printk(XENLOG_ERR "ffa: partition info size invalid: %u\n", fpi_size); + return false; + } subscr_vm_created_count = 0; subscr_vm_destroyed_count = 0; for ( n = 0; n < count; n++ ) { - if ( fpi[n].partition_properties & FFA_PART_PROP_NOTIF_CREATED ) + fpi = ffa_rx + n * fpi_size; + + if ( fpi->partition_properties & FFA_PART_PROP_NOTIF_CREATED ) subscr_vm_created_count++; - if ( fpi[n].partition_properties & FFA_PART_PROP_NOTIF_DESTROYED ) + if ( fpi->partition_properties & FFA_PART_PROP_NOTIF_DESTROYED ) subscr_vm_destroyed_count++; } @@ -252,10 +297,12 @@ static bool init_subscribers(struct ffa_partition_info_1_1 *fpi, uint16_t count) for ( c_pos = 0, d_pos = 0, n = 0; n < count; n++ ) { - if ( fpi[n].partition_properties & FFA_PART_PROP_NOTIF_CREATED ) - subscr_vm_created[c_pos++] = fpi[n].id; - if ( fpi[n].partition_properties & FFA_PART_PROP_NOTIF_DESTROYED ) - subscr_vm_destroyed[d_pos++] = fpi[n].id; + fpi = ffa_rx + n * fpi_size; + + if ( fpi->partition_properties & FFA_PART_PROP_NOTIF_CREATED ) + subscr_vm_created[c_pos++] = fpi->id; + if ( fpi->partition_properties & FFA_PART_PROP_NOTIF_DESTROYED ) + subscr_vm_destroyed[d_pos++] = fpi->id; } return true; @@ -275,7 +322,7 @@ bool ffa_partinfo_init(void) !ffa_rx || !ffa_tx ) return false; - e = ffa_partition_info_get(0, 0, 0, 0, 0, &count, &fpi_size); + e = ffa_partition_info_get(NULL, 0, &count, &fpi_size); if ( e ) { printk(XENLOG_ERR "ffa: Failed to get list of SPs: %d\n", e); @@ -288,7 +335,7 @@ bool ffa_partinfo_init(void) goto out; } - ret = init_subscribers(ffa_rx, count); + ret = init_subscribers(count, fpi_size); out: ffa_rx_release(); diff --git a/xen/arch/arm/tee/ffa_private.h b/xen/arch/arm/tee/ffa_private.h index 85eb61c13464..e5bc73f9039e 100644 --- a/xen/arch/arm/tee/ffa_private.h +++ b/xen/arch/arm/tee/ffa_private.h @@ -316,9 +316,7 @@ int ffa_handle_mem_reclaim(uint64_t handle, uint32_t flags); bool ffa_partinfo_init(void); int ffa_partinfo_domain_init(struct domain *d); bool ffa_partinfo_domain_destroy(struct domain *d); -int32_t ffa_handle_partition_info_get(uint32_t w1, uint32_t w2, uint32_t w3, - uint32_t w4, uint32_t w5, uint32_t *count, - uint32_t *fpi_size); +void ffa_handle_partition_info_get(struct cpu_user_regs *regs); bool ffa_rxtx_init(void); void ffa_rxtx_destroy(void); From patchwork Wed Nov 27 16:07:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13887178 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B41FED6ACEF for ; Wed, 27 Nov 2024 16:08:35 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.844903.1260462 (Exim 4.92) (envelope-from ) id 1tGKaZ-0004rX-O3; Wed, 27 Nov 2024 16:08:27 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 844903.1260462; Wed, 27 Nov 2024 16:08:27 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tGKaZ-0004qM-Im; Wed, 27 Nov 2024 16:08:27 +0000 Received: by outflank-mailman (input) for mailman id 844903; Wed, 27 Nov 2024 16:08:26 +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 1tGKaY-0002q2-5L for xen-devel@lists.xenproject.org; Wed, 27 Nov 2024 16:08:26 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id d3ff74cd-acd9-11ef-a0cd-8be0dac302b0; Wed, 27 Nov 2024 17:08:23 +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 6F1A31477; Wed, 27 Nov 2024 08:08:53 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.58.181]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 056973F5A1; Wed, 27 Nov 2024 08:08:21 -0800 (PST) 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: d3ff74cd-acd9-11ef-a0cd-8be0dac302b0 X-Custom-Connection: eyJyZW1vdGVpcCI6IjIxNy4xNDAuMTEwLjE3MiIsImhlbG8iOiJmb3NzLmFybS5jb20ifQ== X-Custom-Transaction: eyJpZCI6ImQzZmY3NGNkLWFjZDktMTFlZi1hMGNkLThiZTBkYWMzMDJiMCIsInRzIjoxNzMyNzIzNzA0LjE5Nzk3Nywic2VuZGVyIjoiYmVydHJhbmQubWFycXVpc0Bhcm0uY29tIiwicmVjaXBpZW50IjoieGVuLWRldmVsQGxpc3RzLnhlbnByb2plY3Qub3JnIn0= From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v3 06/10] xen/arm: ffa: Use bit 15 convention for SPs Date: Wed, 27 Nov 2024 17:07:38 +0100 Message-ID: <0b987183498242587f3795e870a7395b132ec9ee.1732702210.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: References: MIME-Version: 1.0 Make use and required to have bit 15 convention respected by secure world (having bit 15 of IDs set for secure endpoints and non-set for non-secure ones). If any secure partition has an ID with bit 15 not set, it will not be possible to contact or detect them. Print an error log during probe for each secure endpoint detected with bit 15 not set. We are switching to this convention because Xen is currently not using VMIDs with bit 15 set so we are sure that no VM will have it set (this is ensured by BUILD_BUG_ON in case this becomes false in the future). It is allowing to easily distinguish between secure and non-secure endpoints, preventing the need to store a list of secure endpoint IDs in Xen. Signed-off-by: Bertrand Marquis --- Changes in v3: - rename real_num to n_limit - remove log of skipped SP due to invalid ID as it is already printed Changes in v2: - rebase --- xen/arch/arm/tee/ffa.c | 22 ++++++++++---- xen/arch/arm/tee/ffa_partinfo.c | 51 +++++++++++++++++++++++++-------- xen/arch/arm/tee/ffa_private.h | 7 +++++ xen/arch/arm/tee/ffa_shm.c | 12 +++++++- 4 files changed, 74 insertions(+), 18 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index 4b283a4de5d0..0026ac9134ad 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -195,6 +195,14 @@ static void handle_msg_send_direct_req(struct cpu_user_regs *regs, uint32_t fid) goto out; } + /* we do not support direct messages to VMs */ + if ( !FFA_ID_IS_SECURE(src_dst & GENMASK(15,0)) ) + { + resp.a0 = FFA_ERROR; + resp.a2 = FFA_RET_NOT_SUPPORTED; + goto out; + } + arg.a1 = src_dst; arg.a2 = get_user_reg(regs, 2) & mask; arg.a3 = get_user_reg(regs, 3) & mask; @@ -391,11 +399,15 @@ static int ffa_domain_init(struct domain *d) if ( !ffa_fw_version ) return -ENODEV; - /* - * We can't use that last possible domain ID or ffa_get_vm_id() would - * cause an overflow. - */ - if ( d->domain_id >= UINT16_MAX) + /* + * We are using the domain_id + 1 as the FF-A ID for VMs as FF-A ID 0 is + * reserved for the hypervisor and we only support secure endpoints using + * FF-A IDs with BIT 15 set to 1 so make sure those are not used by Xen. + */ + BUILD_BUG_ON(DOMID_FIRST_RESERVED >= UINT16_MAX); + BUILD_BUG_ON((DOMID_MASK & BIT(15, U)) != 0); + + if ( d->domain_id >= DOMID_FIRST_RESERVED ) return -ERANGE; ctx = xzalloc(struct ffa_ctx); diff --git a/xen/arch/arm/tee/ffa_partinfo.c b/xen/arch/arm/tee/ffa_partinfo.c index 75a073d090e0..74324e1d9d3f 100644 --- a/xen/arch/arm/tee/ffa_partinfo.c +++ b/xen/arch/arm/tee/ffa_partinfo.c @@ -169,14 +169,23 @@ void ffa_handle_partition_info_get(struct cpu_user_regs *regs) if ( ffa_sp_count > 0 ) { - uint32_t n; + uint32_t n, n_limit = ffa_sp_count; void *src_buf = ffa_rx; /* copy the secure partitions info */ - for ( n = 0; n < ffa_sp_count; n++ ) + for ( n = 0; n < n_limit; n++ ) { - memcpy(dst_buf, src_buf, dst_size); - dst_buf += dst_size; + struct ffa_partition_info_1_1 *fpi = src_buf; + + /* filter out SP not following bit 15 convention if any */ + if ( FFA_ID_IS_SECURE(fpi->id) ) + { + memcpy(dst_buf, src_buf, dst_size); + dst_buf += dst_size; + } + else + ffa_sp_count--; + src_buf += src_size; } } @@ -276,10 +285,25 @@ static bool init_subscribers(uint16_t count, uint32_t fpi_size) { fpi = ffa_rx + n * fpi_size; - if ( fpi->partition_properties & FFA_PART_PROP_NOTIF_CREATED ) - subscr_vm_created_count++; - if ( fpi->partition_properties & FFA_PART_PROP_NOTIF_DESTROYED ) - subscr_vm_destroyed_count++; + /* + * We need to have secure partitions using bit 15 set convention for + * secure partition IDs. + * Inform the user with a log and discard giving created or destroy + * event to those IDs. + */ + if ( !FFA_ID_IS_SECURE(fpi->id) ) + { + printk(XENLOG_ERR "ffa: Firmware is not using bit 15 convention for IDs !!\n" + "ffa: Secure partition with id 0x%04x cannot be used\n", + fpi->id); + } + else + { + if ( fpi->partition_properties & FFA_PART_PROP_NOTIF_CREATED ) + subscr_vm_created_count++; + if ( fpi->partition_properties & FFA_PART_PROP_NOTIF_DESTROYED ) + subscr_vm_destroyed_count++; + } } if ( subscr_vm_created_count ) @@ -299,10 +323,13 @@ static bool init_subscribers(uint16_t count, uint32_t fpi_size) { fpi = ffa_rx + n * fpi_size; - if ( fpi->partition_properties & FFA_PART_PROP_NOTIF_CREATED ) - subscr_vm_created[c_pos++] = fpi->id; - if ( fpi->partition_properties & FFA_PART_PROP_NOTIF_DESTROYED ) - subscr_vm_destroyed[d_pos++] = fpi->id; + if ( FFA_ID_IS_SECURE(fpi->id) ) + { + if ( fpi->partition_properties & FFA_PART_PROP_NOTIF_CREATED ) + subscr_vm_created[c_pos++] = fpi->id; + if ( fpi->partition_properties & FFA_PART_PROP_NOTIF_DESTROYED ) + subscr_vm_destroyed[d_pos++] = fpi->id; + } } return true; diff --git a/xen/arch/arm/tee/ffa_private.h b/xen/arch/arm/tee/ffa_private.h index e5bc73f9039e..afe69b43dbef 100644 --- a/xen/arch/arm/tee/ffa_private.h +++ b/xen/arch/arm/tee/ffa_private.h @@ -108,6 +108,13 @@ */ #define FFA_CTX_TEARDOWN_DELAY SECONDS(1) +/* + * We rely on the convention suggested but not mandated by the FF-A + * specification that secure world endpoint identifiers have the bit 15 + * set and normal world have it set to 0. + */ +#define FFA_ID_IS_SECURE(id) ((id) & BIT(15, U)) + /* FF-A-1.1-REL0 section 10.9.2 Memory region handle, page 167 */ #define FFA_HANDLE_HYP_FLAG BIT(63, ULL) #define FFA_HANDLE_INVALID 0xffffffffffffffffULL diff --git a/xen/arch/arm/tee/ffa_shm.c b/xen/arch/arm/tee/ffa_shm.c index efa5b67db8e1..29675f9ba3f7 100644 --- a/xen/arch/arm/tee/ffa_shm.c +++ b/xen/arch/arm/tee/ffa_shm.c @@ -469,6 +469,7 @@ void ffa_handle_mem_share(struct cpu_user_regs *regs) int ret = FFA_RET_DENIED; uint32_t range_count; uint32_t region_offs; + uint16_t dst_id; if ( !ffa_fw_supports_fid(FFA_MEM_SHARE_64) ) { @@ -537,6 +538,15 @@ void ffa_handle_mem_share(struct cpu_user_regs *regs) goto out_unlock; mem_access = ctx->tx + trans.mem_access_offs; + + dst_id = ACCESS_ONCE(mem_access->access_perm.endpoint_id); + if ( !FFA_ID_IS_SECURE(dst_id) ) + { + /* we do not support sharing with VMs */ + ret = FFA_RET_NOT_SUPPORTED; + goto out_unlock; + } + if ( ACCESS_ONCE(mem_access->access_perm.perm) != FFA_MEM_ACC_RW ) { ret = FFA_RET_NOT_SUPPORTED; @@ -567,7 +577,7 @@ void ffa_handle_mem_share(struct cpu_user_regs *regs) goto out_unlock; } shm->sender_id = trans.sender_id; - shm->ep_id = ACCESS_ONCE(mem_access->access_perm.endpoint_id); + shm->ep_id = dst_id; /* * Check that the Composite memory region descriptor fits. From patchwork Wed Nov 27 16:07:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13887179 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D0194D6ACF2 for ; Wed, 27 Nov 2024 16:08:37 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.844904.1260477 (Exim 4.92) (envelope-from ) id 1tGKab-0005JX-Dh; Wed, 27 Nov 2024 16:08:29 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 844904.1260477; Wed, 27 Nov 2024 16:08:29 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tGKab-0005Id-5u; Wed, 27 Nov 2024 16:08:29 +0000 Received: by outflank-mailman (input) for mailman id 844904; Wed, 27 Nov 2024 16:08:28 +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 1tGKaa-0002q2-AG for xen-devel@lists.xenproject.org; Wed, 27 Nov 2024 16:08:28 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id d50566b6-acd9-11ef-a0cd-8be0dac302b0; Wed, 27 Nov 2024 17:08:25 +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 23A8F244B; Wed, 27 Nov 2024 08:08:55 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.58.181]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id BC0AD3F5A1; Wed, 27 Nov 2024 08:08:23 -0800 (PST) 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: d50566b6-acd9-11ef-a0cd-8be0dac302b0 X-Custom-Connection: eyJyZW1vdGVpcCI6IjIxNy4xNDAuMTEwLjE3MiIsImhlbG8iOiJmb3NzLmFybS5jb20ifQ== X-Custom-Transaction: eyJpZCI6ImQ1MDU2NmI2LWFjZDktMTFlZi1hMGNkLThiZTBkYWMzMDJiMCIsInRzIjoxNzMyNzIzNzA1Ljk2MzI5NCwic2VuZGVyIjoiYmVydHJhbmQubWFycXVpc0Bhcm0uY29tIiwicmVjaXBpZW50IjoieGVuLWRldmVsQGxpc3RzLnhlbnByb2plY3Qub3JnIn0= From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v3 07/10] xen/arm: ffa: Transmit RXTX buffers to the SPMC Date: Wed, 27 Nov 2024 17:07:39 +0100 Message-ID: <56217f2f7b4c29a5f84fb02de3f4cbb8342c5560.1732702210.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: References: MIME-Version: 1.0 When an RXTX buffer is mapped by a VM transmit it to the SPMC when it supports RX_ACQUIRE. As a consequence of that, we must acquire the RX buffer of a VM from the SPMC when we want to use it: - create a generic acquire and release function to get the rx buffer of a VM which gets it from the SPMC when supported - rename the rx_acquire to hyp_rx_acquire to remove confusion - rework the rx_lock to only lock access to rx_is_free and only allow usage of the rx buffer to one who managed to acquire it, thus removing the trylock and returning busy if rx_is_free is false As part of this change move some structure definition to ffa_private from ffa_shm as those are need for the MAP call with the SPMC. While there also fix ffa_handle_rxtx_map which was testing the wrong variable after getting the page for the rx buffer, testing tx_pg instead of rx_pg. Fixes: be75f686eb03 ("xen/arm: ffa: separate rxtx buffer routines") Signed-off-by: Bertrand Marquis --- Changes in v3: - add a comment to explain why we only release the RX buffer if an error occurs during partition_info_get - fix the BUILD_BUG_ON check for TX buffer size in rxtx_map (coding style and use PAGE_SIZE * NUM_PAGE) - remove invalid 3 argument to ffa_rxtx_map when forwarding the call to the SPMC - fix bug in ffa_handle_rxtx_map testing wrong variable Changes in v2: - unmap VM rxtx buffer in SPMC on unmap call or on VM destroy - rework the unmap call to the SPMC to properly pass the VM ID --- xen/arch/arm/tee/ffa.c | 2 +- xen/arch/arm/tee/ffa_partinfo.c | 36 ++++--- xen/arch/arm/tee/ffa_private.h | 22 ++++- xen/arch/arm/tee/ffa_rxtx.c | 161 ++++++++++++++++++++++++++------ xen/arch/arm/tee/ffa_shm.c | 15 --- 5 files changed, 170 insertions(+), 66 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index 0026ac9134ad..bc2722d53fd7 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -347,7 +347,7 @@ static bool ffa_handle_call(struct cpu_user_regs *regs) ffa_handle_partition_info_get(regs); return true; case FFA_RX_RELEASE: - e = ffa_handle_rx_release(); + e = ffa_rx_release(d); break; case FFA_MSG_SEND_DIRECT_REQ_32: case FFA_MSG_SEND_DIRECT_REQ_64: diff --git a/xen/arch/arm/tee/ffa_partinfo.c b/xen/arch/arm/tee/ffa_partinfo.c index 74324e1d9d3f..939ed49dd3da 100644 --- a/xen/arch/arm/tee/ffa_partinfo.c +++ b/xen/arch/arm/tee/ffa_partinfo.c @@ -121,11 +121,9 @@ void ffa_handle_partition_info_get(struct cpu_user_regs *regs) goto out; } - if ( !spin_trylock(&ctx->rx_lock) ) - { - ret = FFA_RET_BUSY; + ret = ffa_rx_acquire(d); + if ( ret != FFA_RET_OK ) goto out; - } dst_buf = ctx->rx; @@ -135,22 +133,16 @@ void ffa_handle_partition_info_get(struct cpu_user_regs *regs) goto out_rx_release; } - if ( !ctx->page_count || !ctx->rx_is_free ) - { - ret = FFA_RET_DENIED; - goto out_rx_release; - } - spin_lock(&ffa_rx_buffer_lock); ret = ffa_partition_info_get(uuid, 0, &ffa_sp_count, &src_size); if ( ret ) - goto out_rx_buf_unlock; + goto out_rx_hyp_unlock; /* * ffa_partition_info_get() succeeded so we now own the RX buffer we - * share with the SPMC. We must give it back using ffa_rx_release() + * share with the SPMC. We must give it back using ffa_hyp_rx_release() * once we've copied the content. */ @@ -190,15 +182,20 @@ void ffa_handle_partition_info_get(struct cpu_user_regs *regs) } } - ctx->rx_is_free = false; - out_rx_hyp_release: - ffa_rx_release(); -out_rx_buf_unlock: + ffa_hyp_rx_release(); +out_rx_hyp_unlock: spin_unlock(&ffa_rx_buffer_lock); out_rx_release: - spin_unlock(&ctx->rx_lock); - + /* + * The calling VM RX buffer only contains data to be used by the VM if the + * call was successfull, in which case the VM has to release the buffer + * once it has used the data. + * If something went wrong during the call, we have to release the RX + * buffer back to the SPMC as the VM will not do it. + */ + if ( ret != FFA_RET_OK ) + ffa_rx_release(d); out: if ( ret ) ffa_set_regs_error(regs, ret); @@ -365,8 +362,7 @@ bool ffa_partinfo_init(void) ret = init_subscribers(count, fpi_size); out: - ffa_rx_release(); - + ffa_hyp_rx_release(); return ret; } diff --git a/xen/arch/arm/tee/ffa_private.h b/xen/arch/arm/tee/ffa_private.h index afe69b43dbef..9adfe687c3c9 100644 --- a/xen/arch/arm/tee/ffa_private.h +++ b/xen/arch/arm/tee/ffa_private.h @@ -265,6 +265,21 @@ #define FFA_ABI_BITNUM(id) ((FFA_ABI_ID(id) - FFA_ABI_MIN) << 1 | \ FFA_ABI_CONV(id)) +/* Constituent memory region descriptor */ +struct ffa_address_range { + uint64_t address; + uint32_t page_count; + uint32_t reserved; +}; + +/* Composite memory region descriptor */ +struct ffa_mem_region { + uint32_t total_page_count; + uint32_t address_range_count; + uint64_t reserved; + struct ffa_address_range address_range_array[]; +}; + struct ffa_ctx_notif { bool enabled; @@ -292,7 +307,7 @@ struct ffa_ctx { struct ffa_ctx_notif notif; /* * tx_lock is used to serialize access to tx - * rx_lock is used to serialize access to rx + * rx_lock is used to serialize access to rx_is_free * lock is used for the rest in this struct */ spinlock_t tx_lock; @@ -331,7 +346,8 @@ void ffa_rxtx_domain_destroy(struct domain *d); uint32_t ffa_handle_rxtx_map(uint32_t fid, register_t tx_addr, register_t rx_addr, uint32_t page_count); uint32_t ffa_handle_rxtx_unmap(void); -int32_t ffa_handle_rx_release(void); +int32_t ffa_rx_acquire(struct domain *d); +int32_t ffa_rx_release(struct domain *d); void ffa_notif_init(void); void ffa_notif_init_interrupt(void); @@ -420,7 +436,7 @@ static inline int32_t ffa_simple_call(uint32_t fid, register_t a1, return ffa_get_ret_code(&resp); } -static inline int32_t ffa_rx_release(void) +static inline int32_t ffa_hyp_rx_release(void) { return ffa_simple_call(FFA_RX_RELEASE, 0, 0, 0, 0); } diff --git a/xen/arch/arm/tee/ffa_rxtx.c b/xen/arch/arm/tee/ffa_rxtx.c index 132a7982407b..e1cab7fa5e46 100644 --- a/xen/arch/arm/tee/ffa_rxtx.c +++ b/xen/arch/arm/tee/ffa_rxtx.c @@ -30,6 +30,17 @@ struct ffa_endpoint_rxtx_descriptor_1_1 { uint32_t tx_region_offs; }; +static int32_t ffa_rxtx_map(paddr_t tx_addr, paddr_t rx_addr, + uint32_t page_count) +{ + return ffa_simple_call(FFA_RXTX_MAP_64, tx_addr, rx_addr, page_count, 0); +} + +static int32_t ffa_rxtx_unmap(uint16_t id) +{ + return ffa_simple_call(FFA_RXTX_UNMAP, ((uint64_t)id)<<16, 0, 0, 0); +} + uint32_t ffa_handle_rxtx_map(uint32_t fid, register_t tx_addr, register_t rx_addr, uint32_t page_count) { @@ -42,6 +53,9 @@ uint32_t ffa_handle_rxtx_map(uint32_t fid, register_t tx_addr, void *rx; void *tx; + /* The code is considering that we only get one page for now */ + BUILD_BUG_ON(FFA_MAX_RXTX_PAGE_COUNT != 1); + if ( !smccc_is_conv_64(fid) ) { /* @@ -72,7 +86,7 @@ uint32_t ffa_handle_rxtx_map(uint32_t fid, register_t tx_addr, goto err_put_tx_pg; rx_pg = get_page_from_gfn(d, gfn_x(gaddr_to_gfn(rx_addr)), &t, P2M_ALLOC); - if ( !tx_pg ) + if ( !rx_pg ) goto err_put_tx_pg; /* Only normal RW RAM for now */ @@ -87,6 +101,66 @@ uint32_t ffa_handle_rxtx_map(uint32_t fid, register_t tx_addr, if ( !rx ) goto err_unmap_tx; + /* + * Transmit the RX/TX buffer information to the SPM if acquire is supported + * as the spec says that if not there is not need to acquire/release/map + * rxtx buffers from the SPMC + */ + if ( ffa_fw_supports_fid(FFA_RX_ACQUIRE) ) + { + struct ffa_endpoint_rxtx_descriptor_1_1 *rxtx_desc; + struct ffa_mem_region *mem_reg; + + /* All must fit in our TX buffer */ + BUILD_BUG_ON(sizeof(*rxtx_desc) + sizeof(*mem_reg) * 2 + + sizeof(struct ffa_address_range) * 2 > + FFA_MAX_RXTX_PAGE_COUNT * FFA_PAGE_SIZE); + + spin_lock(&ffa_tx_buffer_lock); + rxtx_desc = ffa_tx; + + /* + * We have only one page for each so we pack everything: + * - rx region descriptor + * - rx region range + * - tx region descriptor + * - tx region range + */ + rxtx_desc->sender_id = ffa_get_vm_id(d); + rxtx_desc->reserved = 0; + rxtx_desc->rx_region_offs = sizeof(*rxtx_desc); + rxtx_desc->tx_region_offs = sizeof(*rxtx_desc) + + offsetof(struct ffa_mem_region, + address_range_array[1]); + + /* rx buffer */ + mem_reg = ffa_tx + sizeof(*rxtx_desc); + mem_reg->total_page_count = 1; + mem_reg->address_range_count = 1; + mem_reg->reserved = 0; + + mem_reg->address_range_array[0].address = page_to_maddr(rx_pg); + mem_reg->address_range_array[0].page_count = 1; + mem_reg->address_range_array[0].reserved = 0; + + /* tx buffer */ + mem_reg = ffa_tx + rxtx_desc->tx_region_offs; + mem_reg->total_page_count = 1; + mem_reg->address_range_count = 1; + mem_reg->reserved = 0; + + mem_reg->address_range_array[0].address = page_to_maddr(tx_pg); + mem_reg->address_range_array[0].page_count = 1; + mem_reg->address_range_array[0].reserved = 0; + + ret = ffa_rxtx_map(0, 0, 0); + + spin_unlock(&ffa_tx_buffer_lock); + + if ( ret != FFA_RET_OK ) + goto err_unmap_rx; + } + ctx->rx = rx; ctx->tx = tx; ctx->rx_pg = rx_pg; @@ -95,6 +169,8 @@ uint32_t ffa_handle_rxtx_map(uint32_t fid, register_t tx_addr, ctx->rx_is_free = true; return FFA_RET_OK; +err_unmap_rx: + unmap_domain_page_global(rx); err_unmap_tx: unmap_domain_page_global(tx); err_put_rx_pg: @@ -105,8 +181,22 @@ err_put_tx_pg: return ret; } -static void rxtx_unmap(struct ffa_ctx *ctx) +static uint32_t rxtx_unmap(struct domain *d) { + struct ffa_ctx *ctx = d->arch.tee; + + if ( !ctx->page_count ) + return FFA_RET_INVALID_PARAMETERS; + + if ( ffa_fw_supports_fid(FFA_RX_ACQUIRE) ) + { + uint32_t ret; + + ret = ffa_rxtx_unmap(ffa_get_vm_id(d)); + if ( ret != FFA_RET_OK ) + return ret; + } + unmap_domain_page_global(ctx->rx); unmap_domain_page_global(ctx->tx); put_page(ctx->rx_pg); @@ -117,32 +207,63 @@ static void rxtx_unmap(struct ffa_ctx *ctx) ctx->tx_pg = NULL; ctx->page_count = 0; ctx->rx_is_free = false; + + return FFA_RET_OK; } uint32_t ffa_handle_rxtx_unmap(void) { - struct domain *d = current->domain; + return rxtx_unmap(current->domain); +} + +int32_t ffa_rx_acquire(struct domain *d) +{ + int32_t ret = FFA_RET_OK; struct ffa_ctx *ctx = d->arch.tee; - if ( !ctx->rx ) - return FFA_RET_INVALID_PARAMETERS; + spin_lock(&ctx->rx_lock); - rxtx_unmap(ctx); + if ( !ctx->page_count ) + { + ret = FFA_RET_DENIED; + goto out; + } - return FFA_RET_OK; + if ( !ctx->rx_is_free ) + { + ret = FFA_RET_BUSY; + goto out; + } + + if ( ffa_fw_supports_fid(FFA_RX_ACQUIRE) ) + { + ret = ffa_simple_call(FFA_RX_ACQUIRE, ffa_get_vm_id(d), 0, 0, 0); + if ( ret != FFA_RET_OK ) + goto out; + } + ctx->rx_is_free = false; +out: + spin_unlock(&ctx->rx_lock); + + return ret; } -int32_t ffa_handle_rx_release(void) +int32_t ffa_rx_release(struct domain *d) { int32_t ret = FFA_RET_DENIED; - struct domain *d = current->domain; struct ffa_ctx *ctx = d->arch.tee; - if ( !spin_trylock(&ctx->rx_lock) ) - return FFA_RET_BUSY; + spin_lock(&ctx->rx_lock); if ( !ctx->page_count || ctx->rx_is_free ) goto out; + + if ( ffa_fw_supports_fid(FFA_RX_ACQUIRE) ) + { + ret = ffa_simple_call(FFA_RX_RELEASE, ffa_get_vm_id(d), 0, 0, 0); + if ( ret != FFA_RET_OK ) + goto out; + } ret = FFA_RET_OK; ctx->rx_is_free = true; out: @@ -151,23 +272,9 @@ out: return ret; } -static int32_t ffa_rxtx_map(paddr_t tx_addr, paddr_t rx_addr, - uint32_t page_count) -{ - return ffa_simple_call(FFA_RXTX_MAP_64, tx_addr, rx_addr, page_count, 0); -} - -static int32_t ffa_rxtx_unmap(void) -{ - return ffa_simple_call(FFA_RXTX_UNMAP, 0, 0, 0, 0); -} - void ffa_rxtx_domain_destroy(struct domain *d) { - struct ffa_ctx *ctx = d->arch.tee; - - if ( ctx->rx ) - rxtx_unmap(ctx); + rxtx_unmap(d); } void ffa_rxtx_destroy(void) @@ -186,7 +293,7 @@ void ffa_rxtx_destroy(void) } if ( need_unmap ) - ffa_rxtx_unmap(); + ffa_rxtx_unmap(0); } bool ffa_rxtx_init(void) diff --git a/xen/arch/arm/tee/ffa_shm.c b/xen/arch/arm/tee/ffa_shm.c index 29675f9ba3f7..d628c1b70609 100644 --- a/xen/arch/arm/tee/ffa_shm.c +++ b/xen/arch/arm/tee/ffa_shm.c @@ -16,21 +16,6 @@ #include "ffa_private.h" -/* Constituent memory region descriptor */ -struct ffa_address_range { - uint64_t address; - uint32_t page_count; - uint32_t reserved; -}; - -/* Composite memory region descriptor */ -struct ffa_mem_region { - uint32_t total_page_count; - uint32_t address_range_count; - uint64_t reserved; - struct ffa_address_range address_range_array[]; -}; - /* Memory access permissions descriptor */ struct ffa_mem_access_perm { uint16_t endpoint_id; From patchwork Wed Nov 27 16:07:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13887177 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D84C9D6ACF1 for ; Wed, 27 Nov 2024 16:08:35 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.844909.1260489 (Exim 4.92) (envelope-from ) id 1tGKad-0005nF-T9; Wed, 27 Nov 2024 16:08:31 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 844909.1260489; Wed, 27 Nov 2024 16:08:31 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tGKad-0005lv-J4; Wed, 27 Nov 2024 16:08:31 +0000 Received: by outflank-mailman (input) for mailman id 844909; Wed, 27 Nov 2024 16:08:30 +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 1tGKac-0002q2-1M for xen-devel@lists.xenproject.org; Wed, 27 Nov 2024 16:08:30 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id d6619fab-acd9-11ef-a0cd-8be0dac302b0; Wed, 27 Nov 2024 17:08:27 +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 90B2E1477; Wed, 27 Nov 2024 08:08:57 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.58.181]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A39BD3F5A1; Wed, 27 Nov 2024 08:08:25 -0800 (PST) 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: d6619fab-acd9-11ef-a0cd-8be0dac302b0 X-Custom-Connection: eyJyZW1vdGVpcCI6IjIxNy4xNDAuMTEwLjE3MiIsImhlbG8iOiJmb3NzLmFybS5jb20ifQ== X-Custom-Transaction: eyJpZCI6ImQ2NjE5ZmFiLWFjZDktMTFlZi1hMGNkLThiZTBkYWMzMDJiMCIsInRzIjoxNzMyNzIzNzA4LjA1NjM4Nywic2VuZGVyIjoiYmVydHJhbmQubWFycXVpc0Bhcm0uY29tIiwicmVjaXBpZW50IjoieGVuLWRldmVsQGxpc3RzLnhlbnByb2plY3Qub3JnIn0= From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v3 08/10] xen/arm: ffa: move message function into ffa_msg.c Date: Wed, 27 Nov 2024 17:07:40 +0100 Message-ID: X-Mailer: git-send-email 2.47.0 In-Reply-To: References: MIME-Version: 1.0 Move the direct message handling function in its own source file and rename it to have a ffa_ prefix. This is a preparation to add support for indirect messages which will go into this newly created source file. Signed-off-by: Bertrand Marquis Reviewed-by: Jens Wiklander --- Changes in v3: - add Jens R-b Changes in v2: - rebase --- xen/arch/arm/tee/Makefile | 1 + xen/arch/arm/tee/ffa.c | 69 +---------------------------- xen/arch/arm/tee/ffa_msg.c | 80 ++++++++++++++++++++++++++++++++++ xen/arch/arm/tee/ffa_private.h | 2 + 4 files changed, 84 insertions(+), 68 deletions(-) create mode 100644 xen/arch/arm/tee/ffa_msg.c diff --git a/xen/arch/arm/tee/Makefile b/xen/arch/arm/tee/Makefile index 7c0f46f7f446..0848c833fec3 100644 --- a/xen/arch/arm/tee/Makefile +++ b/xen/arch/arm/tee/Makefile @@ -3,5 +3,6 @@ obj-$(CONFIG_FFA) += ffa_shm.o obj-$(CONFIG_FFA) += ffa_partinfo.o obj-$(CONFIG_FFA) += ffa_rxtx.o obj-$(CONFIG_FFA) += ffa_notif.o +obj-$(CONFIG_FFA) += ffa_msg.o obj-y += tee.o obj-$(CONFIG_OPTEE) += optee.o diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index bc2722d53fd7..8488fe6af9c0 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -167,73 +167,6 @@ static void handle_version(struct cpu_user_regs *regs) ffa_set_regs(regs, FFA_MY_VERSION, 0, 0, 0, 0, 0, 0, 0); } -static void handle_msg_send_direct_req(struct cpu_user_regs *regs, uint32_t fid) -{ - struct arm_smccc_1_2_regs arg = { .a0 = fid, }; - struct arm_smccc_1_2_regs resp = { }; - struct domain *d = current->domain; - uint32_t src_dst; - uint64_t mask; - - if ( smccc_is_conv_64(fid) ) - mask = GENMASK_ULL(63, 0); - else - mask = GENMASK_ULL(31, 0); - - if ( !ffa_fw_supports_fid(fid) ) - { - resp.a0 = FFA_ERROR; - resp.a2 = FFA_RET_NOT_SUPPORTED; - goto out; - } - - src_dst = get_user_reg(regs, 1); - if ( (src_dst >> 16) != ffa_get_vm_id(d) ) - { - resp.a0 = FFA_ERROR; - resp.a2 = FFA_RET_INVALID_PARAMETERS; - goto out; - } - - /* we do not support direct messages to VMs */ - if ( !FFA_ID_IS_SECURE(src_dst & GENMASK(15,0)) ) - { - resp.a0 = FFA_ERROR; - resp.a2 = FFA_RET_NOT_SUPPORTED; - goto out; - } - - arg.a1 = src_dst; - arg.a2 = get_user_reg(regs, 2) & mask; - arg.a3 = get_user_reg(regs, 3) & mask; - arg.a4 = get_user_reg(regs, 4) & mask; - arg.a5 = get_user_reg(regs, 5) & mask; - arg.a6 = get_user_reg(regs, 6) & mask; - arg.a7 = get_user_reg(regs, 7) & mask; - - arm_smccc_1_2_smc(&arg, &resp); - switch ( resp.a0 ) - { - case FFA_ERROR: - case FFA_SUCCESS_32: - case FFA_SUCCESS_64: - case FFA_MSG_SEND_DIRECT_RESP_32: - case FFA_MSG_SEND_DIRECT_RESP_64: - break; - default: - /* Bad fid, report back to the caller. */ - memset(&resp, 0, sizeof(resp)); - resp.a0 = FFA_ERROR; - resp.a1 = src_dst; - resp.a2 = FFA_RET_ABORTED; - } - -out: - ffa_set_regs(regs, resp.a0, resp.a1 & mask, resp.a2 & mask, resp.a3 & mask, - resp.a4 & mask, resp.a5 & mask, resp.a6 & mask, - resp.a7 & mask); -} - static void handle_features(struct cpu_user_regs *regs) { struct domain *d = current->domain; @@ -351,7 +284,7 @@ static bool ffa_handle_call(struct cpu_user_regs *regs) break; case FFA_MSG_SEND_DIRECT_REQ_32: case FFA_MSG_SEND_DIRECT_REQ_64: - handle_msg_send_direct_req(regs, fid); + ffa_handle_msg_send_direct_req(regs, fid); return true; case FFA_MEM_SHARE_32: case FFA_MEM_SHARE_64: diff --git a/xen/arch/arm/tee/ffa_msg.c b/xen/arch/arm/tee/ffa_msg.c new file mode 100644 index 000000000000..ae263e54890e --- /dev/null +++ b/xen/arch/arm/tee/ffa_msg.c @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 Linaro Limited + */ + +#include +#include +#include + +#include +#include + +#include "ffa_private.h" + +void ffa_handle_msg_send_direct_req(struct cpu_user_regs *regs, uint32_t fid) +{ + struct arm_smccc_1_2_regs arg = { .a0 = fid, }; + struct arm_smccc_1_2_regs resp = { }; + struct domain *d = current->domain; + uint32_t src_dst; + uint64_t mask; + + if ( smccc_is_conv_64(fid) ) + mask = GENMASK_ULL(63, 0); + else + mask = GENMASK_ULL(31, 0); + + if ( !ffa_fw_supports_fid(fid) ) + { + resp.a0 = FFA_ERROR; + resp.a2 = FFA_RET_NOT_SUPPORTED; + goto out; + } + + src_dst = get_user_reg(regs, 1); + if ( (src_dst >> 16) != ffa_get_vm_id(d) ) + { + resp.a0 = FFA_ERROR; + resp.a2 = FFA_RET_INVALID_PARAMETERS; + goto out; + } + + /* we do not support direct messages to VMs */ + if ( !FFA_ID_IS_SECURE(src_dst & GENMASK(15,0)) ) + { + resp.a0 = FFA_ERROR; + resp.a2 = FFA_RET_NOT_SUPPORTED; + goto out; + } + + arg.a1 = src_dst; + arg.a2 = get_user_reg(regs, 2) & mask; + arg.a3 = get_user_reg(regs, 3) & mask; + arg.a4 = get_user_reg(regs, 4) & mask; + arg.a5 = get_user_reg(regs, 5) & mask; + arg.a6 = get_user_reg(regs, 6) & mask; + arg.a7 = get_user_reg(regs, 7) & mask; + + arm_smccc_1_2_smc(&arg, &resp); + switch ( resp.a0 ) + { + case FFA_ERROR: + case FFA_SUCCESS_32: + case FFA_SUCCESS_64: + case FFA_MSG_SEND_DIRECT_RESP_32: + case FFA_MSG_SEND_DIRECT_RESP_64: + break; + default: + /* Bad fid, report back to the caller. */ + memset(&resp, 0, sizeof(resp)); + resp.a0 = FFA_ERROR; + resp.a1 = src_dst; + resp.a2 = FFA_RET_ABORTED; + } + +out: + ffa_set_regs(regs, resp.a0, resp.a1 & mask, resp.a2 & mask, resp.a3 & mask, + resp.a4 & mask, resp.a5 & mask, resp.a6 & mask, + resp.a7 & mask); +} diff --git a/xen/arch/arm/tee/ffa_private.h b/xen/arch/arm/tee/ffa_private.h index 9adfe687c3c9..02162e0ee4c7 100644 --- a/xen/arch/arm/tee/ffa_private.h +++ b/xen/arch/arm/tee/ffa_private.h @@ -360,6 +360,8 @@ void ffa_handle_notification_info_get(struct cpu_user_regs *regs); void ffa_handle_notification_get(struct cpu_user_regs *regs); int ffa_handle_notification_set(struct cpu_user_regs *regs); +void ffa_handle_msg_send_direct_req(struct cpu_user_regs *regs, uint32_t fid); + static inline uint16_t ffa_get_vm_id(const struct domain *d) { /* +1 since 0 is reserved for the hypervisor in FF-A */ From patchwork Wed Nov 27 16:07:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13887182 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 12A5ED6ACF1 for ; Wed, 27 Nov 2024 16:10:40 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.844949.1260499 (Exim 4.92) (envelope-from ) id 1tGKca-0000mJ-AS; Wed, 27 Nov 2024 16:10:32 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 844949.1260499; Wed, 27 Nov 2024 16:10:32 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tGKca-0000mC-3t; Wed, 27 Nov 2024 16:10:32 +0000 Received: by outflank-mailman (input) for mailman id 844949; Wed, 27 Nov 2024 16:10:30 +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 1tGKae-0002q2-M2 for xen-devel@lists.xenproject.org; Wed, 27 Nov 2024 16:08:32 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id d7f30500-acd9-11ef-a0cd-8be0dac302b0; Wed, 27 Nov 2024 17:08:30 +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 0212A150C; Wed, 27 Nov 2024 08:09:00 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.58.181]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id DDF273F5A1; Wed, 27 Nov 2024 08:08:27 -0800 (PST) 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: d7f30500-acd9-11ef-a0cd-8be0dac302b0 X-Custom-Connection: eyJyZW1vdGVpcCI6IjIxNy4xNDAuMTEwLjE3MiIsImhlbG8iOiJmb3NzLmFybS5jb20ifQ== X-Custom-Transaction: eyJpZCI6ImQ3ZjMwNTAwLWFjZDktMTFlZi1hMGNkLThiZTBkYWMzMDJiMCIsInRzIjoxNzMyNzIzNzEwLjg1OTU1NCwic2VuZGVyIjoiYmVydHJhbmQubWFycXVpc0Bhcm0uY29tIiwicmVjaXBpZW50IjoieGVuLWRldmVsQGxpc3RzLnhlbnByb2plY3Qub3JnIn0= From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v3 09/10] xen/arm: ffa: Remove per VM notif_enabled Date: Wed, 27 Nov 2024 17:07:41 +0100 Message-ID: <8e7cf913eeba955f8ed6bced1cafdf264dcb4318.1732702210.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: References: MIME-Version: 1.0 Remove the per VM flag to store if notifications are enabled or not as the only case where they are not, if notifications are enabled globally, will make the VM creation fail. Also use the opportunity to always give the notifications interrupts IDs to VM. If the firmware does not support notifications, there won't be any generated and setting one will give back a NOT_SUPPORTED. Signed-off-by: Bertrand Marquis --- Changes in v3: - Add a comment explaining why it is ok to call bitmap destroy even if bitmap create failed. Changes in v2: - rebase --- xen/arch/arm/tee/ffa.c | 17 +++-------------- xen/arch/arm/tee/ffa_notif.c | 14 +++++--------- xen/arch/arm/tee/ffa_private.h | 2 -- 3 files changed, 8 insertions(+), 25 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index 8488fe6af9c0..04d2403415fe 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -169,8 +169,6 @@ static void handle_version(struct cpu_user_regs *regs) static void handle_features(struct cpu_user_regs *regs) { - struct domain *d = current->domain; - struct ffa_ctx *ctx = d->arch.tee; uint32_t a1 = get_user_reg(regs, 1); unsigned int n; @@ -218,16 +216,10 @@ static void handle_features(struct cpu_user_regs *regs) ffa_set_regs_success(regs, 0, 0); break; case FFA_FEATURE_NOTIF_PEND_INTR: - if ( ctx->notif.enabled ) - ffa_set_regs_success(regs, GUEST_FFA_NOTIF_PEND_INTR_ID, 0); - else - ffa_set_regs_error(regs, FFA_RET_NOT_SUPPORTED); + ffa_set_regs_success(regs, GUEST_FFA_NOTIF_PEND_INTR_ID, 0); break; case FFA_FEATURE_SCHEDULE_RECV_INTR: - if ( ctx->notif.enabled ) - ffa_set_regs_success(regs, GUEST_FFA_SCHEDULE_RECV_INTR_ID, 0); - else - ffa_set_regs_error(regs, FFA_RET_NOT_SUPPORTED); + ffa_set_regs_success(regs, GUEST_FFA_SCHEDULE_RECV_INTR_ID, 0); break; case FFA_NOTIFICATION_BIND: @@ -236,10 +228,7 @@ static void handle_features(struct cpu_user_regs *regs) case FFA_NOTIFICATION_SET: case FFA_NOTIFICATION_INFO_GET_32: case FFA_NOTIFICATION_INFO_GET_64: - if ( ctx->notif.enabled ) - ffa_set_regs_success(regs, 0, 0); - else - ffa_set_regs_error(regs, FFA_RET_NOT_SUPPORTED); + ffa_set_regs_success(regs, 0, 0); break; default: ffa_set_regs_error(regs, FFA_RET_NOT_SUPPORTED); diff --git a/xen/arch/arm/tee/ffa_notif.c b/xen/arch/arm/tee/ffa_notif.c index 4b3e46318f4b..21b9e78f6399 100644 --- a/xen/arch/arm/tee/ffa_notif.c +++ b/xen/arch/arm/tee/ffa_notif.c @@ -405,7 +405,6 @@ void ffa_notif_init(void) int ffa_notif_domain_init(struct domain *d) { - struct ffa_ctx *ctx = d->arch.tee; int32_t res; if ( !notif_enabled ) @@ -415,18 +414,15 @@ int ffa_notif_domain_init(struct domain *d) if ( res ) return -ENOMEM; - ctx->notif.enabled = true; - return 0; } void ffa_notif_domain_destroy(struct domain *d) { - struct ffa_ctx *ctx = d->arch.tee; - - if ( ctx->notif.enabled ) - { + /* + * Call bitmap_destroy even if bitmap create failed as the SPMC will + * return a DENIED error that we will ignore. + */ + if ( notif_enabled ) ffa_notification_bitmap_destroy(ffa_get_vm_id(d)); - ctx->notif.enabled = false; - } } diff --git a/xen/arch/arm/tee/ffa_private.h b/xen/arch/arm/tee/ffa_private.h index 02162e0ee4c7..973ee55be09b 100644 --- a/xen/arch/arm/tee/ffa_private.h +++ b/xen/arch/arm/tee/ffa_private.h @@ -281,8 +281,6 @@ struct ffa_mem_region { }; struct ffa_ctx_notif { - bool enabled; - /* * True if domain is reported by FFA_NOTIFICATION_INFO_GET to have * pending global notifications. From patchwork Wed Nov 27 16:07:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13887183 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3467FD6ACF1 for ; Wed, 27 Nov 2024 16:10:43 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.844973.1260508 (Exim 4.92) (envelope-from ) id 1tGKcd-00015b-HM; Wed, 27 Nov 2024 16:10:35 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 844973.1260508; Wed, 27 Nov 2024 16:10:35 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1tGKcd-00015U-EG; Wed, 27 Nov 2024 16:10:35 +0000 Received: by outflank-mailman (input) for mailman id 844973; Wed, 27 Nov 2024 16:10:34 +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 1tGKag-0002q2-Hi for xen-devel@lists.xenproject.org; Wed, 27 Nov 2024 16:08:34 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id d904da3d-acd9-11ef-a0cd-8be0dac302b0; Wed, 27 Nov 2024 17:08:32 +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 C15561477; Wed, 27 Nov 2024 08:09:01 -0800 (PST) Received: from C3HXLD123V.arm.com (unknown [10.57.58.181]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 5C8BD3F5A1; Wed, 27 Nov 2024 08:08:30 -0800 (PST) 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: d904da3d-acd9-11ef-a0cd-8be0dac302b0 X-Custom-Connection: eyJyZW1vdGVpcCI6IjIxNy4xNDAuMTEwLjE3MiIsImhlbG8iOiJmb3NzLmFybS5jb20ifQ== X-Custom-Transaction: eyJpZCI6ImQ5MDRkYTNkLWFjZDktMTFlZi1hMGNkLThiZTBkYWMzMDJiMCIsInRzIjoxNzMyNzIzNzEyLjY3Mjg4NSwic2VuZGVyIjoiYmVydHJhbmQubWFycXVpc0Bhcm0uY29tIiwicmVjaXBpZW50IjoieGVuLWRldmVsQGxpc3RzLnhlbnByb2plY3Qub3JnIn0= From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v3 10/10] xen/arm: ffa: Add indirect message support Date: Wed, 27 Nov 2024 17:07:42 +0100 Message-ID: <7b3dc2c98d01478d5ab03780932844ea980b7ae0.1732702210.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.47.0 In-Reply-To: References: MIME-Version: 1.0 Add support for FFA_MSG_SEND2 to send indirect messages from a VM to a secure partition. Signed-off-by: Bertrand Marquis --- Changes in v3: - in ffa_handle_msg_send2 use ffa_get_vm_id instead of a local variable to make sure that we use the right VM ID as source without having a potential solution for the VM to give a wrong identity. Changes in v2: - rebase --- xen/arch/arm/tee/ffa.c | 5 ++++ xen/arch/arm/tee/ffa_msg.c | 50 ++++++++++++++++++++++++++++++++++ xen/arch/arm/tee/ffa_private.h | 1 + 3 files changed, 56 insertions(+) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index 04d2403415fe..87775ed88ffd 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -101,6 +101,7 @@ static const struct ffa_fw_abi ffa_fw_abi_needed[] = { FW_ABI(FFA_MEM_RECLAIM), FW_ABI(FFA_MSG_SEND_DIRECT_REQ_32), FW_ABI(FFA_MSG_SEND_DIRECT_REQ_64), + FW_ABI(FFA_MSG_SEND2), }; /* @@ -195,6 +196,7 @@ static void handle_features(struct cpu_user_regs *regs) case FFA_PARTITION_INFO_GET: case FFA_MSG_SEND_DIRECT_REQ_32: case FFA_MSG_SEND_DIRECT_REQ_64: + case FFA_MSG_SEND2: ffa_set_regs_success(regs, 0, 0); break; case FFA_MEM_SHARE_64: @@ -275,6 +277,9 @@ static bool ffa_handle_call(struct cpu_user_regs *regs) case FFA_MSG_SEND_DIRECT_REQ_64: ffa_handle_msg_send_direct_req(regs, fid); return true; + case FFA_MSG_SEND2: + e = ffa_handle_msg_send2(regs); + break; case FFA_MEM_SHARE_32: case FFA_MEM_SHARE_64: ffa_handle_mem_share(regs); diff --git a/xen/arch/arm/tee/ffa_msg.c b/xen/arch/arm/tee/ffa_msg.c index ae263e54890e..ee594e737fc7 100644 --- a/xen/arch/arm/tee/ffa_msg.c +++ b/xen/arch/arm/tee/ffa_msg.c @@ -12,6 +12,15 @@ #include "ffa_private.h" +/* Encoding of partition message in RX/TX buffer */ +struct ffa_part_msg_rxtx { + uint32_t flags; + uint32_t reserved; + uint32_t msg_offset; + uint32_t send_recv_id; + uint32_t msg_size; +}; + void ffa_handle_msg_send_direct_req(struct cpu_user_regs *regs, uint32_t fid) { struct arm_smccc_1_2_regs arg = { .a0 = fid, }; @@ -78,3 +87,44 @@ out: resp.a4 & mask, resp.a5 & mask, resp.a6 & mask, resp.a7 & mask); } + +int32_t ffa_handle_msg_send2(struct cpu_user_regs *regs) +{ + struct domain *src_d = current->domain; + struct ffa_ctx *src_ctx = src_d->arch.tee; + const struct ffa_part_msg_rxtx *src_msg; + uint16_t dst_id, src_id; + int32_t ret; + + if ( !ffa_fw_supports_fid(FFA_MSG_SEND2) ) + return FFA_RET_NOT_SUPPORTED; + + if ( !spin_trylock(&src_ctx->tx_lock) ) + return FFA_RET_BUSY; + + src_msg = src_ctx->tx; + src_id = src_msg->send_recv_id >> 16; + dst_id = src_msg->send_recv_id & GENMASK(15,0); + + if ( src_id != ffa_get_vm_id(src_d) || !FFA_ID_IS_SECURE(dst_id) ) + { + ret = FFA_RET_INVALID_PARAMETERS; + goto out_unlock_tx; + } + + /* check source message fits in buffer */ + if ( src_ctx->page_count * FFA_PAGE_SIZE < + src_msg->msg_offset + src_msg->msg_size || + src_msg->msg_offset < sizeof(struct ffa_part_msg_rxtx) ) + { + ret = FFA_RET_INVALID_PARAMETERS; + goto out_unlock_tx; + } + + ret = ffa_simple_call(FFA_MSG_SEND2, + ((uint32_t)ffa_get_vm_id(src_d)) << 16, 0, 0, 0); + +out_unlock_tx: + spin_unlock(&src_ctx->tx_lock); + return ret; +} diff --git a/xen/arch/arm/tee/ffa_private.h b/xen/arch/arm/tee/ffa_private.h index 973ee55be09b..d441c0ca5598 100644 --- a/xen/arch/arm/tee/ffa_private.h +++ b/xen/arch/arm/tee/ffa_private.h @@ -359,6 +359,7 @@ void ffa_handle_notification_get(struct cpu_user_regs *regs); int ffa_handle_notification_set(struct cpu_user_regs *regs); void ffa_handle_msg_send_direct_req(struct cpu_user_regs *regs, uint32_t fid); +int32_t ffa_handle_msg_send2(struct cpu_user_regs *regs); static inline uint16_t ffa_get_vm_id(const struct domain *d) {