From patchwork Wed Oct 16 08:31:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13837923 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 09747D1AD2D for ; Wed, 16 Oct 2024 08:32:42 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.819600.1232990 (Exim 4.92) (envelope-from ) id 1t0zSB-0000PS-QK; Wed, 16 Oct 2024 08:32:23 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 819600.1232990; Wed, 16 Oct 2024 08:32:23 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1t0zSB-0000PL-Le; Wed, 16 Oct 2024 08:32:23 +0000 Received: by outflank-mailman (input) for mailman id 819600; Wed, 16 Oct 2024 08:32: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 1t0zSA-0000Nz-8m for xen-devel@lists.xenproject.org; Wed, 16 Oct 2024 08:32:22 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 28341bea-8b99-11ef-a0be-8be0dac302b0; Wed, 16 Oct 2024 10:32:20 +0200 (CEST) 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 89261FEC; Wed, 16 Oct 2024 01:32:48 -0700 (PDT) Received: from C3HXLD123V.arm.com (unknown [10.57.21.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9F35F3F71E; Wed, 16 Oct 2024 01:32:17 -0700 (PDT) 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: 28341bea-8b99-11ef-a0be-8be0dac302b0 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v2 01/10] xen/arm: ffa: Rework firmware discovery Date: Wed, 16 Oct 2024 10:31:21 +0200 Message-ID: <457020b684e87ee9ad9488a4ec0d17ade90fdea1.1729066788.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 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 | 44 ++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index 022089278e1c..1cc4023135d5 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,24 @@ 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; + 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 +548,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 +572,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; } From patchwork Wed Oct 16 08:31:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13837922 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 954EAD1AD2C for ; Wed, 16 Oct 2024 08:32:40 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.819601.1233000 (Exim 4.92) (envelope-from ) id 1t0zSC-0000el-Vw; Wed, 16 Oct 2024 08:32:24 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 819601.1233000; Wed, 16 Oct 2024 08:32: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 1t0zSC-0000ec-T4; Wed, 16 Oct 2024 08:32:24 +0000 Received: by outflank-mailman (input) for mailman id 819601; Wed, 16 Oct 2024 08:32:23 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1t0zSA-00006U-Uu for xen-devel@lists.xenproject.org; Wed, 16 Oct 2024 08:32:22 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 293d9897-8b99-11ef-99a3-01e77a169b0f; Wed, 16 Oct 2024 10:32:21 +0200 (CEST) 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 375531007; Wed, 16 Oct 2024 01:32:50 -0700 (PDT) Received: from C3HXLD123V.arm.com (unknown [10.57.21.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 40E6E3F71E; Wed, 16 Oct 2024 01:32:19 -0700 (PDT) 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: 293d9897-8b99-11ef-99a3-01e77a169b0f From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v2 02/10] xen/arm: ffa: Rework feature discovery Date: Wed, 16 Oct 2024 10:31:22 +0200 Message-ID: <8cc7abbd82b43aa595ddc2dce3495663dfc413e0.1729066788.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 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 1cc4023135d5..dde932422ecf 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 { + const 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) @@ -540,17 +554,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 Oct 16 08:31:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13837920 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 C95C4D1AD2B for ; Wed, 16 Oct 2024 08:32:33 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.819602.1233004 (Exim 4.92) (envelope-from ) id 1t0zSD-0000i3-9s; Wed, 16 Oct 2024 08:32:25 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 819602.1233004; Wed, 16 Oct 2024 08:32:25 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1t0zSD-0000h8-5v; Wed, 16 Oct 2024 08:32:25 +0000 Received: by outflank-mailman (input) for mailman id 819602; Wed, 16 Oct 2024 08:32:23 +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 1t0zSB-0000Nz-K3 for xen-devel@lists.xenproject.org; Wed, 16 Oct 2024 08:32:23 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 2a4e3d8a-8b99-11ef-a0be-8be0dac302b0; Wed, 16 Oct 2024 10:32:23 +0200 (CEST) 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 1F4D8FEC; Wed, 16 Oct 2024 01:32:52 -0700 (PDT) Received: from C3HXLD123V.arm.com (unknown [10.57.21.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id EA7F63F71E; Wed, 16 Oct 2024 01:32:20 -0700 (PDT) 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: 2a4e3d8a-8b99-11ef-a0be-8be0dac302b0 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v2 03/10] xen/arm: ffa: Fix version negotiation Date: Wed, 16 Oct 2024 10:31:23 +0200 Message-ID: <86636401aa34f9c64e674a53d49859930a227d10.1729066788.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 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 | 54 +++++++++++++++++++++++++--------- xen/arch/arm/tee/ffa_private.h | 3 ++ 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index dde932422ecf..1ee6b2895e92 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,18 +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 @@ -564,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 Oct 16 08:31:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13837921 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 DDDC5D1AD2A for ; Wed, 16 Oct 2024 08:32:35 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.819603.1233020 (Exim 4.92) (envelope-from ) id 1t0zSF-0001Ej-OV; Wed, 16 Oct 2024 08:32:27 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 819603.1233020; Wed, 16 Oct 2024 08:32: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 1t0zSF-0001Ec-LU; Wed, 16 Oct 2024 08:32:27 +0000 Received: by outflank-mailman (input) for mailman id 819603; Wed, 16 Oct 2024 08:32: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 1t0zSE-00006U-OC for xen-devel@lists.xenproject.org; Wed, 16 Oct 2024 08:32:26 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 2b7aa259-8b99-11ef-99a3-01e77a169b0f; Wed, 16 Oct 2024 10:32:25 +0200 (CEST) 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 1015D1007; Wed, 16 Oct 2024 01:32:54 -0700 (PDT) Received: from C3HXLD123V.arm.com (unknown [10.57.21.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id DDD763F71E; Wed, 16 Oct 2024 01:32:22 -0700 (PDT) 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: 2b7aa259-8b99-11ef-99a3-01e77a169b0f From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v2 04/10] xen/arm: ffa: Fine granular call support Date: Wed, 16 Oct 2024 10:31:24 +0200 Message-ID: <84a39fbb681c1fdc2708d385e79bef1bbc9c6ae0.1729066788.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 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 1ee6b2895e92..267d4435ac08 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 { const 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 661764052e67..b6931c855779 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 Oct 16 08:31:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13837925 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 89CD1D1AD2A for ; Wed, 16 Oct 2024 08:32:47 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.819604.1233030 (Exim 4.92) (envelope-from ) id 1t0zSH-0001V4-2f; Wed, 16 Oct 2024 08:32:29 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 819604.1233030; Wed, 16 Oct 2024 08:32: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 1t0zSG-0001Uq-Um; Wed, 16 Oct 2024 08:32:28 +0000 Received: by outflank-mailman (input) for mailman id 819604; Wed, 16 Oct 2024 08:32:27 +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 1t0zSF-0000Nz-Ad for xen-devel@lists.xenproject.org; Wed, 16 Oct 2024 08:32:27 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 2c838c0f-8b99-11ef-a0be-8be0dac302b0; Wed, 16 Oct 2024 10:32:26 +0200 (CEST) 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 CCA60FEC; Wed, 16 Oct 2024 01:32:55 -0700 (PDT) Received: from C3HXLD123V.arm.com (unknown [10.57.21.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id C5DFC3F71E; Wed, 16 Oct 2024 01:32:24 -0700 (PDT) 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: 2c838c0f-8b99-11ef-a0be-8be0dac302b0 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v2 05/10] xen/arm: ffa: Rework partition info get Date: Wed, 16 Oct 2024 10:31:25 +0200 Message-ID: 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 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 267d4435ac08..4b55e8b48f01 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 Oct 16 08:31:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13837926 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 59ED4D1AD2B for ; Wed, 16 Oct 2024 08:32:48 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.819605.1233040 (Exim 4.92) (envelope-from ) id 1t0zSJ-0001nN-BR; Wed, 16 Oct 2024 08:32:31 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 819605.1233040; Wed, 16 Oct 2024 08:32: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 1t0zSJ-0001nA-7W; Wed, 16 Oct 2024 08:32:31 +0000 Received: by outflank-mailman (input) for mailman id 819605; Wed, 16 Oct 2024 08:32:29 +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 1t0zSH-0000Nz-15 for xen-devel@lists.xenproject.org; Wed, 16 Oct 2024 08:32:29 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 2d772929-8b99-11ef-a0be-8be0dac302b0; Wed, 16 Oct 2024 10:32:28 +0200 (CEST) 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 6ADE11007; Wed, 16 Oct 2024 01:32:57 -0700 (PDT) Received: from C3HXLD123V.arm.com (unknown [10.57.21.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 8447D3F71E; Wed, 16 Oct 2024 01:32:26 -0700 (PDT) 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: 2d772929-8b99-11ef-a0be-8be0dac302b0 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v2 06/10] xen/arm: ffa: Use bit 15 convention for SPs Date: Wed, 16 Oct 2024 10:31:26 +0200 Message-ID: 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 v2: - rebase --- xen/arch/arm/tee/ffa.c | 22 +++++++++++--- xen/arch/arm/tee/ffa_partinfo.c | 54 +++++++++++++++++++++++++-------- xen/arch/arm/tee/ffa_private.h | 7 +++++ xen/arch/arm/tee/ffa_shm.c | 12 +++++++- 4 files changed, 77 insertions(+), 18 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index 4b55e8b48f01..a292003ca9fe 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..3cf801523296 100644 --- a/xen/arch/arm/tee/ffa_partinfo.c +++ b/xen/arch/arm/tee/ffa_partinfo.c @@ -169,14 +169,26 @@ void ffa_handle_partition_info_get(struct cpu_user_regs *regs) if ( ffa_sp_count > 0 ) { - uint32_t n; + uint32_t n, real_num = 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 < real_num; 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 + { + printk(XENLOG_INFO "ffa: sp id 0x%04x skipped, bit 15 is 0\n", + fpi->id); + ffa_sp_count--; + } src_buf += src_size; } } @@ -276,10 +288,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 +326,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 Oct 16 08:31:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13837927 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 A7DC0D1AD2A for ; Wed, 16 Oct 2024 08:32:50 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.819607.1233051 (Exim 4.92) (envelope-from ) id 1t0zSK-00025q-Tm; Wed, 16 Oct 2024 08:32:32 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 819607.1233051; Wed, 16 Oct 2024 08:32: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 1t0zSK-00025e-OA; Wed, 16 Oct 2024 08:32:32 +0000 Received: by outflank-mailman (input) for mailman id 819607; Wed, 16 Oct 2024 08:32: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 1t0zSI-0000Nz-RN for xen-devel@lists.xenproject.org; Wed, 16 Oct 2024 08:32:30 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 2e9cdc9f-8b99-11ef-a0be-8be0dac302b0; Wed, 16 Oct 2024 10:32:30 +0200 (CEST) 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 57468FEC; Wed, 16 Oct 2024 01:32:59 -0700 (PDT) Received: from C3HXLD123V.arm.com (unknown [10.57.21.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 22BD13F71E; Wed, 16 Oct 2024 01:32:27 -0700 (PDT) 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: 2e9cdc9f-8b99-11ef-a0be-8be0dac302b0 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v2 07/10] xen/arm: ffa: Transmit RXTX buffers to the SPMC Date: Wed, 16 Oct 2024 10:31:27 +0200 Message-ID: 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. Signed-off-by: Bertrand Marquis --- 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 | 29 ++---- xen/arch/arm/tee/ffa_private.h | 22 ++++- xen/arch/arm/tee/ffa_rxtx.c | 158 ++++++++++++++++++++++++++------ xen/arch/arm/tee/ffa_shm.c | 15 --- 5 files changed, 161 insertions(+), 65 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index a292003ca9fe..40ea5398fa21 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 3cf801523296..fde187dba4e5 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. */ @@ -193,15 +185,13 @@ 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); - + if ( ret != FFA_RET_OK ) + ffa_rx_release(d); out: if ( ret ) ffa_set_regs_error(regs, ret); @@ -368,8 +358,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 b6931c855779..a5d43e51f843 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) ) { /* @@ -87,6 +101,65 @@ 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_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, 1); + + 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 +168,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 +180,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 +206,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 +271,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 +292,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 Oct 16 08:31:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13837928 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 6CECCD1AD2B for ; Wed, 16 Oct 2024 08:32:52 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.819608.1233060 (Exim 4.92) (envelope-from ) id 1t0zSM-0002Mr-7r; Wed, 16 Oct 2024 08:32:34 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 819608.1233060; Wed, 16 Oct 2024 08:32:34 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1t0zSM-0002MA-2o; Wed, 16 Oct 2024 08:32:34 +0000 Received: by outflank-mailman (input) for mailman id 819608; Wed, 16 Oct 2024 08:32:32 +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 1t0zSK-0000Nz-J4 for xen-devel@lists.xenproject.org; Wed, 16 Oct 2024 08:32:32 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 2fa7210e-8b99-11ef-a0be-8be0dac302b0; Wed, 16 Oct 2024 10:32:32 +0200 (CEST) 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 11D0C1007; Wed, 16 Oct 2024 01:33:01 -0700 (PDT) Received: from C3HXLD123V.arm.com (unknown [10.57.21.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 2C06B3F71E; Wed, 16 Oct 2024 01:32:29 -0700 (PDT) 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: 2fa7210e-8b99-11ef-a0be-8be0dac302b0 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v2 08/10] xen/arm: ffa: move message function into ffa_msg.c Date: Wed, 16 Oct 2024 10:31:28 +0200 Message-ID: <480245789e126e5ee0d6d21b5946cdf2efb873ea.1729066788.git.bertrand.marquis@arm.com> 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 --- 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 40ea5398fa21..72826b49d2aa 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 Oct 16 08:31:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13837924 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 A8922D1AD2B for ; Wed, 16 Oct 2024 08:32:43 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.819610.1233070 (Exim 4.92) (envelope-from ) id 1t0zSN-0002jF-MC; Wed, 16 Oct 2024 08:32:35 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 819610.1233070; Wed, 16 Oct 2024 08:32: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 1t0zSN-0002ib-Ex; Wed, 16 Oct 2024 08:32:35 +0000 Received: by outflank-mailman (input) for mailman id 819610; Wed, 16 Oct 2024 08:32: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 1t0zSM-0000Nz-9n for xen-devel@lists.xenproject.org; Wed, 16 Oct 2024 08:32:34 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 30a74f6c-8b99-11ef-a0be-8be0dac302b0; Wed, 16 Oct 2024 10:32:33 +0200 (CEST) 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 B6B5BFEC; Wed, 16 Oct 2024 01:33:02 -0700 (PDT) Received: from C3HXLD123V.arm.com (unknown [10.57.21.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id BD68E3F71E; Wed, 16 Oct 2024 01:32:31 -0700 (PDT) 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: 30a74f6c-8b99-11ef-a0be-8be0dac302b0 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v2 09/10] xen/arm: ffa: Remove per VM notif_enabled Date: Wed, 16 Oct 2024 10:31:29 +0200 Message-ID: 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 v2: - rebase --- xen/arch/arm/tee/ffa.c | 17 +++-------------- xen/arch/arm/tee/ffa_notif.c | 10 +--------- xen/arch/arm/tee/ffa_private.h | 2 -- 3 files changed, 4 insertions(+), 25 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index 72826b49d2aa..3a9525aa4598 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..3c6418e62e2b 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,11 @@ 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 ) - { + 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 Oct 16 08:31:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13837929 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 D4407D1AD2B for ; Wed, 16 Oct 2024 08:32:56 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.819613.1233081 (Exim 4.92) (envelope-from ) id 1t0zSR-0003Ib-3X; Wed, 16 Oct 2024 08:32:39 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 819613.1233081; Wed, 16 Oct 2024 08:32:39 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1t0zSQ-0003IL-Rt; Wed, 16 Oct 2024 08:32:38 +0000 Received: by outflank-mailman (input) for mailman id 819613; Wed, 16 Oct 2024 08:32:37 +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 1t0zSP-00006U-1I for xen-devel@lists.xenproject.org; Wed, 16 Oct 2024 08:32:37 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 31a22474-8b99-11ef-99a3-01e77a169b0f; Wed, 16 Oct 2024 10:32:35 +0200 (CEST) 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 55CF41007; Wed, 16 Oct 2024 01:33:04 -0700 (PDT) Received: from C3HXLD123V.arm.com (unknown [10.57.21.81]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 7006F3F71E; Wed, 16 Oct 2024 01:32:33 -0700 (PDT) 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: 31a22474-8b99-11ef-99a3-01e77a169b0f From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: jens.wiklander@linaro.org, Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH v2 10/10] xen/arm: ffa: Add indirect message support Date: Wed, 16 Oct 2024 10:31:30 +0200 Message-ID: <9464941b06e82763ebe79e3f2adb4ca2497cf298.1729066788.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 v2: - rebase --- xen/arch/arm/tee/ffa.c | 5 ++++ xen/arch/arm/tee/ffa_msg.c | 49 ++++++++++++++++++++++++++++++++++ xen/arch/arm/tee/ffa_private.h | 1 + 3 files changed, 55 insertions(+) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index 3a9525aa4598..21d41b452dc9 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..335f246ba657 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,43 @@ 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)src_id) << 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) {