From patchwork Thu Sep 19 12:19:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13807671 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 A2F43CAC5B5 for ; Thu, 19 Sep 2024 12:19:55 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.800667.1210625 (Exim 4.92) (envelope-from ) id 1srG8R-0003zr-Re; Thu, 19 Sep 2024 12:19:47 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 800667.1210625; Thu, 19 Sep 2024 12:19:47 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1srG8R-0003zj-Og; Thu, 19 Sep 2024 12:19:47 +0000 Received: by outflank-mailman (input) for mailman id 800667; Thu, 19 Sep 2024 12:19:46 +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 1srG8Q-0003zB-Ty for xen-devel@lists.xenproject.org; Thu, 19 Sep 2024 12:19:46 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 74d1a7b7-7681-11ef-a0b8-8be0dac302b0; Thu, 19 Sep 2024 14:19:45 +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 94D291007; Thu, 19 Sep 2024 05:20:14 -0700 (PDT) Received: from C3HXLD123V.emea.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 521863F64C; Thu, 19 Sep 2024 05:19:44 -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: 74d1a7b7-7681-11ef-a0b8-8be0dac302b0 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 01/10] xen/arm: ffa: Rework firmware discovery Date: Thu, 19 Sep 2024 14:19:01 +0200 Message-Id: <9931c299450a1e0a2384161eb9b514ead8895ecc.1726676338.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.39.5 (Apple Git-154) 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 --- xen/arch/arm/tee/ffa.c | 52 +++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index 022089278e1c..7c84aa6aa43d 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,25 +514,21 @@ 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, "ffa: FFA_VERSION returned not supported\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); - /* * 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 @@ -546,12 +542,24 @@ 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; + 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); + + 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_INFO "ARM FF-A No firmware support\n"); return false; } From patchwork Thu Sep 19 12:19:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13807676 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 F2920CE8D7D for ; Thu, 19 Sep 2024 12:20:03 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.800668.1210635 (Exim 4.92) (envelope-from ) id 1srG8T-0004FZ-39; Thu, 19 Sep 2024 12:19:49 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 800668.1210635; Thu, 19 Sep 2024 12:19:49 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1srG8T-0004FN-08; Thu, 19 Sep 2024 12:19:49 +0000 Received: by outflank-mailman (input) for mailman id 800668; Thu, 19 Sep 2024 12:19:47 +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 1srG8R-0003zB-K2 for xen-devel@lists.xenproject.org; Thu, 19 Sep 2024 12:19:47 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 75813cf7-7681-11ef-a0b8-8be0dac302b0; Thu, 19 Sep 2024 14:19:46 +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 B5EDD13D5; Thu, 19 Sep 2024 05:20:15 -0700 (PDT) Received: from C3HXLD123V.emea.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 69A553F64C; Thu, 19 Sep 2024 05:19:45 -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: 75813cf7-7681-11ef-a0b8-8be0dac302b0 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 02/10] xen/arm: ffa: Rework feature discovery Date: Thu, 19 Sep 2024 14:19:02 +0200 Message-Id: <6c841c341b7dc9e06eb1c02555e30b29bd400d20.1726676338.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.39.5 (Apple Git-154) 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 --- xen/arch/arm/tee/ffa.c | 61 +++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index 7c84aa6aa43d..7ff2529b2055 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -74,6 +74,24 @@ /* Negotiated FF-A version to use with the SPMC, 0 if not there or supported */ static uint32_t __ro_after_init ffa_fw_version; +/* List of ABI we use from the firmware */ +static const uint32_t ffa_fw_feat_needed[] = { + FFA_VERSION, + FFA_FEATURES, + FFA_NOTIFICATION_BITMAP_CREATE, + FFA_NOTIFICATION_BITMAP_DESTROY, + FFA_PARTITION_INFO_GET, + FFA_NOTIFICATION_INFO_GET_64, + FFA_NOTIFICATION_GET, + FFA_RX_RELEASE, + FFA_RXTX_MAP_64, + FFA_RXTX_UNMAP, + FFA_MEM_SHARE_32, + FFA_MEM_SHARE_64, + FFA_MEM_RECLAIM, + FFA_MSG_SEND_DIRECT_REQ_32, + FFA_MSG_SEND_DIRECT_REQ_64, +}; /* * Our rx/tx buffers shared with the SPMC. FFA_RXTX_PAGE_COUNT is the @@ -112,20 +130,9 @@ static bool ffa_get_version(uint32_t *vers) return true; } -static int32_t ffa_features(uint32_t id) +static bool ffa_feature_supported(uint32_t id) { - return ffa_simple_call(FFA_FEATURES, id, 0, 0, 0); -} - -static bool check_mandatory_feature(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) @@ -529,24 +536,6 @@ static bool ffa_probe(void) goto err_no_fw; } - /* - * 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. - */ - 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) ) - { - printk(XENLOG_ERR "ffa: Mandatory feature not supported by fw\n"); - goto err_no_fw; - } - major_vers = (vers >> FFA_VERSION_MAJOR_SHIFT) & FFA_VERSION_MAJOR_MASK; minor_vers = vers & FFA_VERSION_MINOR_MASK; @@ -555,6 +544,16 @@ static bool ffa_probe(void) ffa_fw_version = vers; + for ( int i = 0; i < ARRAY_SIZE(ffa_fw_feat_needed); i++ ) + { + if ( !ffa_feature_supported(ffa_fw_feat_needed[i]) ) + { + printk(XENLOG_INFO "ARM FF-A Firmware does not support 0x%08x\n", + ffa_fw_feat_needed[i]); + goto err_no_fw; + } + } + if ( !ffa_rxtx_init() ) { printk(XENLOG_ERR "ffa: Error during RXTX buffer init\n"); From patchwork Thu Sep 19 12:19:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13807672 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 246D9CE8D7D for ; Thu, 19 Sep 2024 12:19:59 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.800669.1210644 (Exim 4.92) (envelope-from ) id 1srG8V-0004WJ-Ay; Thu, 19 Sep 2024 12:19:51 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 800669.1210644; Thu, 19 Sep 2024 12:19:51 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1srG8V-0004WB-80; Thu, 19 Sep 2024 12:19:51 +0000 Received: by outflank-mailman (input) for mailman id 800669; Thu, 19 Sep 2024 12:19:49 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1srG8T-0003iL-Rc for xen-devel@lists.xenproject.org; Thu, 19 Sep 2024 12:19:49 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 76312b0a-7681-11ef-99a2-01e77a169b0f; Thu, 19 Sep 2024 14:19:48 +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 D6D2E1007; Thu, 19 Sep 2024 05:20:16 -0700 (PDT) Received: from C3HXLD123V.emea.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 8B2833F64C; Thu, 19 Sep 2024 05:19:46 -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: 76312b0a-7681-11ef-99a2-01e77a169b0f From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 03/10] xen/arm: ffa: fix version negotiation Date: Thu, 19 Sep 2024 14:19:03 +0200 Message-Id: <716e806316f8249611c8268f781efbea19273b4a.1726676338.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.39.5 (Apple Git-154) In-Reply-To: References: MIME-Version: 1.0 Fix FFA version negotiation with the firmware to follow the specification guidance more closely. 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: - return an error for a different major - return 1.1 for a version >= 1.1 - return 1.0 if 1.0 was requested Signed-off-by: Bertrand Marquis --- xen/arch/arm/tee/ffa.c | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index 7ff2529b2055..1f602f25d097 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -141,13 +141,24 @@ 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; + /** + * As of now we only support 1.0 or 1.1. + * For any 1.x >= 1.1 return OK with 1.1 + * For 1.0 return OK with 1.0 + * For anything else return an error. + */ + if ( (vers >> FFA_VERSION_MAJOR_SHIFT) == FFA_MY_VERSION_MAJOR ) + { + 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); + ctx->guest_vers = vers; + ffa_set_regs(regs, vers, 0, 0, 0, 0, 0, 0, 0); + } + else + ffa_set_regs_error(regs, FFA_RET_NOT_SUPPORTED); } static void handle_msg_send_direct_req(struct cpu_user_regs *regs, uint32_t fid) @@ -530,7 +541,8 @@ static bool ffa_probe(void) goto err_no_fw; } - if ( vers < FFA_MIN_SPMC_VERSION || vers > FFA_MY_VERSION ) + if ( vers < FFA_MIN_SPMC_VERSION || + (vers >> FFA_VERSION_MAJOR_SHIFT) != FFA_MY_VERSION_MAJOR ) { printk(XENLOG_ERR "ffa: Incompatible version %#x found\n", vers); goto err_no_fw; @@ -542,7 +554,17 @@ static bool ffa_probe(void) printk(XENLOG_INFO "ARM FF-A Firmware version %u.%u\n", major_vers, minor_vers); - ffa_fw_version = 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 is rejected before. + */ + if ( vers > FFA_MY_VERSION ) + ffa_fw_version = FFA_MY_VERSION; + else + ffa_fw_version = vers; for ( int i = 0; i < ARRAY_SIZE(ffa_fw_feat_needed); i++ ) { From patchwork Thu Sep 19 12:19:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13807673 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 12E8ECAC5B5 for ; Thu, 19 Sep 2024 12:20:01 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.800670.1210655 (Exim 4.92) (envelope-from ) id 1srG8W-0004pa-KD; Thu, 19 Sep 2024 12:19:52 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 800670.1210655; Thu, 19 Sep 2024 12:19:52 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1srG8W-0004oe-Fj; Thu, 19 Sep 2024 12:19:52 +0000 Received: by outflank-mailman (input) for mailman id 800670; Thu, 19 Sep 2024 12:19:51 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1srG8V-0003iL-25 for xen-devel@lists.xenproject.org; Thu, 19 Sep 2024 12:19:51 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 76d68b02-7681-11ef-99a2-01e77a169b0f; Thu, 19 Sep 2024 14:19:49 +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 F350913D5; Thu, 19 Sep 2024 05:20:17 -0700 (PDT) Received: from C3HXLD123V.emea.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id AD0A33F64C; Thu, 19 Sep 2024 05:19:47 -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: 76d68b02-7681-11ef-99a2-01e77a169b0f From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 04/10] xen/arm: ffa: Fine granular call support Date: Thu, 19 Sep 2024 14:19:04 +0200 Message-Id: X-Mailer: git-send-email 2.39.5 (Apple Git-154) 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 done to the firmware. With this enabled. allow FF-A support to be activated for guest even if the firmware does not support it. As a consequence, if the firmware is not there or not supported, we return an empty list of partitions to VMs requesting it through PARTINFO_GET ABI. Signed-off-by: Bertrand Marquis --- xen/arch/arm/tee/ffa.c | 31 ++++++++++++++++++++----------- xen/arch/arm/tee/ffa_notif.c | 7 +++++++ xen/arch/arm/tee/ffa_partinfo.c | 31 +++++++++++++++++++++++++++++-- xen/arch/arm/tee/ffa_private.h | 28 ++++++++++++++++++++++++++++ xen/arch/arm/tee/ffa_rxtx.c | 13 ++++++------- xen/arch/arm/tee/ffa_shm.c | 12 ++++++++++++ 6 files changed, 102 insertions(+), 20 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index 1f602f25d097..53960b146220 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_feat_supported, FEAT_FUNC_BITMAP_SIZE); /* List of ABI we use from the firmware */ static const uint32_t ffa_fw_feat_needed[] = { @@ -174,6 +177,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) ) { @@ -387,8 +397,6 @@ static int ffa_domain_init(struct domain *d) struct ffa_ctx *ctx; int ret; - if ( !ffa_fw_version ) - return -ENODEV; /* * We can't use that last possible domain ID or ffa_get_vm_id() would * cause an overflow. @@ -523,6 +531,9 @@ static bool ffa_probe(void) printk(XENLOG_INFO "ARM FF-A Mediator version %u.%u\n", FFA_MY_VERSION_MAJOR, FFA_MY_VERSION_MINOR); + INIT_LIST_HEAD(&ffa_teardown_head); + init_timer(&ffa_teardown_timer, ffa_teardown_timer_callback, NULL, 0); + /* * psci_init_smccc() updates this value with what's reported by EL-3 * or secure world. @@ -568,12 +579,12 @@ static bool ffa_probe(void) for ( int i = 0; i < ARRAY_SIZE(ffa_fw_feat_needed); i++ ) { - if ( !ffa_feature_supported(ffa_fw_feat_needed[i]) ) - { + if ( ffa_feature_supported(ffa_fw_feat_needed[i]) ) + set_bit(FEAT_FUNC_BITNUM(ffa_fw_feat_needed[i]), + ffa_fw_feat_supported); + else printk(XENLOG_INFO "ARM FF-A Firmware does not support 0x%08x\n", - ffa_fw_feat_needed[i]); - goto err_no_fw; - } + ffa_fw_feat_needed[i]); } if ( !ffa_rxtx_init() ) @@ -586,8 +597,6 @@ static bool ffa_probe(void) goto err_rxtx_destroy; ffa_notif_init(); - INIT_LIST_HEAD(&ffa_teardown_head); - init_timer(&ffa_teardown_timer, ffa_teardown_timer_callback, NULL, 0); return true; @@ -597,7 +606,7 @@ err_no_fw: ffa_fw_version = 0; printk(XENLOG_INFO "ARM FF-A No firmware support\n"); - return false; + return true; } static const struct tee_mediator_ops ffa_ops = 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..a42bd92ab8cf 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 ) { @@ -267,7 +292,6 @@ bool ffa_partinfo_init(void) out: ffa_rx_release(); - return ret; } @@ -313,6 +337,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 7c6b06f686fc..d4dc9c8cd67b 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 @@ -238,6 +239,23 @@ #define FFA_NOTIFICATION_INFO_GET_32 0x84000083U #define FFA_NOTIFICATION_INFO_GET_64 0xC4000083U +/** + * 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_FUNC_MIN FFA_ERROR +#define FFA_FUNC_MAX FFA_NOTIFICATION_INFO_GET_64 +#define FFA_FUNC_ID(id) ((id) & ARM_SMCCC_FUNC_MASK) +#define FFA_FUNC_CONV(id) (((id) >> ARM_SMCCC_CONV_SHIFT) & BIT(0,U)) + +#define FEAT_FUNC_BITMAP_SIZE (2 * (FFA_FUNC_ID(FFA_FUNC_MAX) - \ + FFA_FUNC_ID(FFA_FUNC_MIN) + 1)) +#define FEAT_FUNC_BITNUM(id) ((FFA_FUNC_ID(id) - \ + FFA_FUNC_ID(FFA_FUNC_MIN)) << 1 | \ + FFA_FUNC_CONV(id)) + struct ffa_ctx_notif { bool enabled; @@ -286,6 +304,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_feat_supported, FEAT_FUNC_BITMAP_SIZE); bool ffa_shm_domain_destroy(struct domain *d); void ffa_handle_mem_share(struct cpu_user_regs *regs); @@ -398,4 +418,12 @@ 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) +{ + if ( ffa_fw_version == 0 ) + return false; + else + return test_bit(FEAT_FUNC_BITNUM(fid), ffa_fw_feat_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..cb54c76911fd 100644 --- a/xen/arch/arm/tee/ffa_rxtx.c +++ b/xen/arch/arm/tee/ffa_rxtx.c @@ -193,24 +193,23 @@ 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; ffa_tx = alloc_xenheap_pages(get_order_from_pages(FFA_RXTX_PAGE_COUNT), 0); if ( !ffa_tx ) - goto err; + return false; 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 false; } return true; - -err: - ffa_rxtx_destroy(); - - 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 Thu Sep 19 12:19:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13807675 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 4D839CCD1A4 for ; Thu, 19 Sep 2024 12:20:03 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.800672.1210667 (Exim 4.92) (envelope-from ) id 1srG8X-00052T-J6; Thu, 19 Sep 2024 12:19:53 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 800672.1210667; Thu, 19 Sep 2024 12:19:53 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1srG8X-0004zZ-AE; Thu, 19 Sep 2024 12:19:53 +0000 Received: by outflank-mailman (input) for mailman id 800672; Thu, 19 Sep 2024 12:19:52 +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 1srG8W-0003iL-7A for xen-devel@lists.xenproject.org; Thu, 19 Sep 2024 12:19:52 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 778474b0-7681-11ef-99a2-01e77a169b0f; Thu, 19 Sep 2024 14:19:50 +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 21B671570; Thu, 19 Sep 2024 05:20:19 -0700 (PDT) Received: from C3HXLD123V.emea.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id C7C123F86F; Thu, 19 Sep 2024 05:19:48 -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: 778474b0-7681-11ef-99a2-01e77a169b0f From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 05/10] xen/arm: ffa: Rework partition info get Date: Thu, 19 Sep 2024 14:19:05 +0200 Message-Id: <46037e19536f8d7ea45ce8c4e1c3f9f1726bcc3b.1726676338.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.39.5 (Apple Git-154) 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 --- 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 53960b146220..beaed63a85ae 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -308,8 +308,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 ) @@ -335,16 +333,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 a42bd92ab8cf..7b59fbdd3ffd 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 d4dc9c8cd67b..089607c1c321 100644 --- a/xen/arch/arm/tee/ffa_private.h +++ b/xen/arch/arm/tee/ffa_private.h @@ -314,9 +314,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 Thu Sep 19 12:19:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13807679 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 BF5BACAC5B5 for ; Thu, 19 Sep 2024 12:20:03 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.800671.1210661 (Exim 4.92) (envelope-from ) id 1srG8X-0004x8-6k; Thu, 19 Sep 2024 12:19:53 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 800671.1210661; Thu, 19 Sep 2024 12:19:53 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1srG8X-0004vn-0A; Thu, 19 Sep 2024 12:19:53 +0000 Received: by outflank-mailman (input) for mailman id 800671; Thu, 19 Sep 2024 12:19:52 +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 1srG8V-0003zB-VO for xen-devel@lists.xenproject.org; Thu, 19 Sep 2024 12:19:51 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 7830e956-7681-11ef-a0b8-8be0dac302b0; Thu, 19 Sep 2024 14:19:51 +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 4625D1007; Thu, 19 Sep 2024 05:20:20 -0700 (PDT) Received: from C3HXLD123V.emea.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id EDB603F64C; Thu, 19 Sep 2024 05:19:49 -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: 7830e956-7681-11ef-a0b8-8be0dac302b0 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 06/10] xen/arm: ffa: Use bit 15 convention for SPs Date: Thu, 19 Sep 2024 14:19:06 +0200 Message-Id: <4c39c1c95a0bfc9e101f9c962a2e96a948b9774d.1726676338.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.39.5 (Apple Git-154) 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 --- 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 beaed63a85ae..45f9c1db8a6e 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -192,6 +192,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; @@ -386,11 +394,15 @@ static int ffa_domain_init(struct domain *d) struct ffa_ctx *ctx; int ret; - /* - * 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 7b59fbdd3ffd..b391b1adf9f2 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 089607c1c321..c6903e335489 100644 --- a/xen/arch/arm/tee/ffa_private.h +++ b/xen/arch/arm/tee/ffa_private.h @@ -105,6 +105,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 Thu Sep 19 12:19:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13807674 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 313D5CAC5BF for ; Thu, 19 Sep 2024 12:20:03 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.800673.1210682 (Exim 4.92) (envelope-from ) id 1srG8Y-0005Yj-Sg; Thu, 19 Sep 2024 12:19:54 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 800673.1210682; Thu, 19 Sep 2024 12:19:54 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1srG8Y-0005WE-Mq; Thu, 19 Sep 2024 12:19:54 +0000 Received: by outflank-mailman (input) for mailman id 800673; Thu, 19 Sep 2024 12:19:53 +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 1srG8W-0003zB-VT for xen-devel@lists.xenproject.org; Thu, 19 Sep 2024 12:19:52 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 78c6d96c-7681-11ef-a0b8-8be0dac302b0; Thu, 19 Sep 2024 14:19:52 +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 68CB613D5; Thu, 19 Sep 2024 05:20:21 -0700 (PDT) Received: from C3HXLD123V.emea.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 1BA8F3F64C; Thu, 19 Sep 2024 05:19:50 -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: 78c6d96c-7681-11ef-a0b8-8be0dac302b0 From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 07/10] xen/arm: ffa: Transmit RXTX buffers to the SPMC Date: Thu, 19 Sep 2024 14:19:07 +0200 Message-Id: <0bb3d0faf5a80112a95363ee9fd023d510e3f0c8.1726676338.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.39.5 (Apple Git-154) 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 --- xen/arch/arm/tee/ffa.c | 2 +- xen/arch/arm/tee/ffa_partinfo.c | 28 +++---- xen/arch/arm/tee/ffa_private.h | 22 +++++- xen/arch/arm/tee/ffa_rxtx.c | 126 ++++++++++++++++++++++++++++---- xen/arch/arm/tee/ffa_shm.c | 15 ---- 5 files changed, 142 insertions(+), 51 deletions(-) diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c index 45f9c1db8a6e..4a769e20007b 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -344,7 +344,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 b391b1adf9f2..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,7 +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 c6903e335489..84b0f866a71e 100644 --- a/xen/arch/arm/tee/ffa_private.h +++ b/xen/arch/arm/tee/ffa_private.h @@ -263,6 +263,21 @@ FFA_FUNC_ID(FFA_FUNC_MIN)) << 1 | \ FFA_FUNC_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; @@ -290,7 +305,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; @@ -329,7 +344,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); @@ -418,7 +434,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 cb54c76911fd..dacf33cc9efc 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(void) +{ + return ffa_simple_call(FFA_RXTX_UNMAP, 0, 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_tx; + } + ctx->rx = rx; ctx->tx = tx; ctx->rx_pg = rx_pg; @@ -132,34 +205,61 @@ uint32_t ffa_handle_rxtx_unmap(void) return FFA_RET_OK; } -int32_t ffa_handle_rx_release(void) +int32_t ffa_rx_acquire(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 ) + if ( !ctx->page_count ) + { + ret = FFA_RET_DENIED; + goto out; + } + + 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; + } ret = FFA_RET_OK; - ctx->rx_is_free = true; + ctx->rx_is_free = false; out: spin_unlock(&ctx->rx_lock); return ret; } -static int32_t ffa_rxtx_map(paddr_t tx_addr, paddr_t rx_addr, - uint32_t page_count) +int32_t ffa_rx_release(struct domain *d) { - return ffa_simple_call(FFA_RXTX_MAP_64, tx_addr, rx_addr, page_count, 0); -} + int32_t ret = FFA_RET_DENIED; + struct ffa_ctx *ctx = d->arch.tee; -static int32_t ffa_rxtx_unmap(void) -{ - return ffa_simple_call(FFA_RXTX_UNMAP, 0, 0, 0, 0); + 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: + spin_unlock(&ctx->rx_lock); + + return ret; } void ffa_rxtx_domain_destroy(struct domain *d) 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 Thu Sep 19 12:19:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13807677 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 C9B3BCDD54F for ; Thu, 19 Sep 2024 12:20:04 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.800674.1210695 (Exim 4.92) (envelope-from ) id 1srG8a-0005wh-II; Thu, 19 Sep 2024 12:19:56 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 800674.1210695; Thu, 19 Sep 2024 12:19:56 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1srG8a-0005w8-Cs; Thu, 19 Sep 2024 12:19:56 +0000 Received: by outflank-mailman (input) for mailman id 800674; Thu, 19 Sep 2024 12:19:55 +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 1srG8Z-0003iL-FD for xen-devel@lists.xenproject.org; Thu, 19 Sep 2024 12:19:55 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 798bbb3a-7681-11ef-99a2-01e77a169b0f; Thu, 19 Sep 2024 14:19:53 +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 84BD71595; Thu, 19 Sep 2024 05:20:22 -0700 (PDT) Received: from C3HXLD123V.emea.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 416783F64C; Thu, 19 Sep 2024 05:19:52 -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: 798bbb3a-7681-11ef-99a2-01e77a169b0f From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 08/10] xen/arm: ffa: move message function into ffa_msg.c Date: Thu, 19 Sep 2024 14:19:08 +0200 Message-Id: <8b4f75f82d25081968b789aaba81eb897c00c176.1726676338.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.39.5 (Apple Git-154) 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 --- 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 4a769e20007b..89c6a1cf06a1 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -164,73 +164,6 @@ static void handle_version(struct cpu_user_regs *regs) ffa_set_regs_error(regs, FFA_RET_NOT_SUPPORTED); } -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; @@ -348,7 +281,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 84b0f866a71e..0be246ff0ae7 100644 --- a/xen/arch/arm/tee/ffa_private.h +++ b/xen/arch/arm/tee/ffa_private.h @@ -358,6 +358,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 Thu Sep 19 12:19:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13807678 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 0B5BECDD552 for ; Thu, 19 Sep 2024 12:20:06 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.800675.1210705 (Exim 4.92) (envelope-from ) id 1srG8b-0006Fw-VK; Thu, 19 Sep 2024 12:19:57 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 800675.1210705; Thu, 19 Sep 2024 12:19:57 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1srG8b-0006FL-P3; Thu, 19 Sep 2024 12:19:57 +0000 Received: by outflank-mailman (input) for mailman id 800675; Thu, 19 Sep 2024 12:19:56 +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 1srG8a-0003iL-HY for xen-devel@lists.xenproject.org; Thu, 19 Sep 2024 12:19:56 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 7a3751b0-7681-11ef-99a2-01e77a169b0f; Thu, 19 Sep 2024 14:19:54 +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 9B8361007; Thu, 19 Sep 2024 05:20:23 -0700 (PDT) Received: from C3HXLD123V.emea.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 5A4CE3F64C; Thu, 19 Sep 2024 05:19:53 -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: 7a3751b0-7681-11ef-99a2-01e77a169b0f From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 09/10] xen/arm: ffa: Remove per VM notif_enabled Date: Thu, 19 Sep 2024 14:19:09 +0200 Message-Id: <948e6e15cf855b4c76dab0d4a779f39edf5e7b52.1726676338.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.39.5 (Apple Git-154) 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 --- 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 89c6a1cf06a1..5d7633dbb3a5 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -166,8 +166,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; @@ -215,16 +213,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: @@ -233,10 +225,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 0be246ff0ae7..5054254540ef 100644 --- a/xen/arch/arm/tee/ffa_private.h +++ b/xen/arch/arm/tee/ffa_private.h @@ -279,8 +279,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 Thu Sep 19 12:19:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bertrand Marquis X-Patchwork-Id: 13807680 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 53AC1CAC5BF for ; Thu, 19 Sep 2024 12:20:07 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.800676.1210714 (Exim 4.92) (envelope-from ) id 1srG8d-0006bA-BB; Thu, 19 Sep 2024 12:19:59 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 800676.1210714; Thu, 19 Sep 2024 12:19:59 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1srG8d-0006Ze-65; Thu, 19 Sep 2024 12:19:59 +0000 Received: by outflank-mailman (input) for mailman id 800676; Thu, 19 Sep 2024 12:19:57 +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 1srG8b-0003iL-Mn for xen-devel@lists.xenproject.org; Thu, 19 Sep 2024 12:19:57 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-flk1.inumbo.com (Halon) with ESMTP id 7adeea31-7681-11ef-99a2-01e77a169b0f; Thu, 19 Sep 2024 14:19:55 +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 B2FE213D5; Thu, 19 Sep 2024 05:20:24 -0700 (PDT) Received: from C3HXLD123V.emea.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 712F83F64C; Thu, 19 Sep 2024 05:19:54 -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: 7adeea31-7681-11ef-99a2-01e77a169b0f From: Bertrand Marquis To: xen-devel@lists.xenproject.org Cc: Volodymyr Babchuk , Stefano Stabellini , Julien Grall , Michal Orzel Subject: [PATCH 10/10] xen/arm: ffa: Add indirect message support Date: Thu, 19 Sep 2024 14:19:10 +0200 Message-Id: <7b6fabf888047c7a2def42b929fb2c60c83ac452.1726676338.git.bertrand.marquis@arm.com> X-Mailer: git-send-email 2.39.5 (Apple Git-154) 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 --- 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 5d7633dbb3a5..abb05e09f6f4 100644 --- a/xen/arch/arm/tee/ffa.c +++ b/xen/arch/arm/tee/ffa.c @@ -94,6 +94,7 @@ static const uint32_t ffa_fw_feat_needed[] = { FFA_MEM_RECLAIM, FFA_MSG_SEND_DIRECT_REQ_32, FFA_MSG_SEND_DIRECT_REQ_64, + FFA_MSG_SEND2, }; /* @@ -192,6 +193,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: @@ -272,6 +274,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 5054254540ef..1bc7b33ec2c7 100644 --- a/xen/arch/arm/tee/ffa_private.h +++ b/xen/arch/arm/tee/ffa_private.h @@ -357,6 +357,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) {