From nobody Mon Feb 9 23:59:51 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1663578797; cv=none; d=zohomail.com; s=zohoarc; b=gklKcsI9HyuvaoEGW/ver6h4iaBPVn9zcTL1+bADSltJqpDC+sJbdNLQ7PrLJDyPq0jX7v+W51QtRc6k/6gR31f8xs84PswKmpV1OZQnHrb2zi/aPLPAp8OieaH1reZoIZKJM+7xOML+hQi9YxMYCFwj1O8o848i6rCeW4pFcrU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1663578797; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=fW+HOuAthe2zj2QR4QYWX0sNZcRkvvPLxIfXZPseyvA=; b=cxDNROKff4I9M4/zt/IkY3nvMGVQ2TCsWbuF2ZejTCC83k4MaydVxfDtSWSeCLt2ikf6I9DKa9GUDRnEJ1NXXLKc8jVluZ9AGE53PFEJgP7O1GjxaC7yRLOaDuvVP67uxAHc9e2r10hcbeG+XYa2lScO0tR1GgzUbKiKb3ztyew= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1663578797778986.8966217148906; Mon, 19 Sep 2022 02:13:17 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.408579.651380 (Exim 4.92) (envelope-from ) id 1oaCpj-0000Dj-74; Mon, 19 Sep 2022 09:12:55 +0000 Received: by outflank-mailman (output) from mailman id 408579.651380; Mon, 19 Sep 2022 09:12:55 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1oaCpj-0000DY-41; Mon, 19 Sep 2022 09:12:55 +0000 Received: by outflank-mailman (input) for mailman id 408579; Mon, 19 Sep 2022 09:12:53 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1oaCph-0007Fl-2L for xen-devel@lists.xenproject.org; Mon, 19 Sep 2022 09:12:53 +0000 Received: from mail-lf1-x132.google.com (mail-lf1-x132.google.com [2a00:1450:4864:20::132]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 3099e9cf-37fb-11ed-bad8-01ff208a15ba; Mon, 19 Sep 2022 11:12:31 +0200 (CEST) Received: by mail-lf1-x132.google.com with SMTP id j16so18854656lfg.1 for ; Mon, 19 Sep 2022 02:12:52 -0700 (PDT) Received: from jade.urgonet (h-79-136-84-253.A175.priv.bahnhof.se. [79.136.84.253]) by smtp.gmail.com with ESMTPSA id f3-20020a05651c02c300b0025fdf1af42asm4815394ljo.78.2022.09.19.02.12.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Sep 2022 02:12:50 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 3099e9cf-37fb-11ed-bad8-01ff208a15ba DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=fW+HOuAthe2zj2QR4QYWX0sNZcRkvvPLxIfXZPseyvA=; b=nJ992wnIUb+QKl4BkCiXrlnk8R0vYbvYNvYisr0vKT8xg8gmeIcCppwFLN/qypUoyq RvXMJKDNUtQR9UoLVpJL+tN3YK7rktI8CWaVqdUGWeV7mcMB29jGWmd29eDU+sBKpK4a r05IPt/H3w9rVoBFECvg3+hbWXVQtgJNNlUeh+zgKD7jHwOzS4Chqachdbg1vQX0r4mg lCEp8+Ycg9oe7l+nEyUXYJ7h2aJbOP203OHzI8UZ2b2FUfV59a8BBkxKkacj6+wgFxl8 Zw8kHDtlDmFBaEELGRcqRpnkfXPQ0ugYyYSGvOsVx91vkjkno2aFD5HikJcJ8bBFDBfE H0Sg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=fW+HOuAthe2zj2QR4QYWX0sNZcRkvvPLxIfXZPseyvA=; b=5/K41PdTpJWXZ3+F9zhd2dJSLoEBB+WGxEzcyF4dlQonazOJuQRBaeXSUon6k7IrFd 8xnGK8vN2vNREDBBRTol6zkR66stp9wkATzeXqtCb3dPno+cEq8HPNsBXtkUOpavo7lm Qa3KTHkgRGxohkJdd1l2ItlFM8hzbjoYpe/8ayypPAgY2e29kWKTJgn1K5WhGld/lzc3 P6BEYdiHZFvRD7ef017Kkywfvw8SmhVtxc3DNtOoPo3KvOLTEcjFQNfx9J4jJEVa1OsF ExjRp8mzuZYR2hJFll+2yiPtWEuv+sS4vWfLVIbBzKNim5ie9liYAJe4tlg0dzDT2n8e snsA== X-Gm-Message-State: ACrzQf2Nw73Rh//tieDdeJ7wn3K4AqFxSv0KhePF8fyY8bEQkpK0p2pv JPHT8907jO6JBe2wSULK1nG5ysFrSbe/UMAU X-Google-Smtp-Source: AMsMyM6gvPM4SAz1fDLYinKsm/IA6OpO80ZaLT3MBqPMIH4pMJUMn4AN+WvD6ZDUunUi/9CUyrIewQ== X-Received: by 2002:a05:6512:10d3:b0:499:cce2:37a8 with SMTP id k19-20020a05651210d300b00499cce237a8mr5674929lfg.169.1663578771228; Mon, 19 Sep 2022 02:12:51 -0700 (PDT) From: Jens Wiklander To: xen-devel@lists.xenproject.org Cc: Stefano Stabellini , Julien Grall , Volodymyr Babchuk , Bertrand.Marquis@arm.com, Anthony PERARD , Juergen Gross , Wei Liu , Marc Bonnici , Achin Gupta , Jens Wiklander Subject: [PATCH v6 5/9] xen/arm: ffa: send guest events to Secure Partitions Date: Mon, 19 Sep 2022 11:12:34 +0200 Message-Id: <20220919091238.2068052-6-jens.wiklander@linaro.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220919091238.2068052-1-jens.wiklander@linaro.org> References: <20220919091238.2068052-1-jens.wiklander@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @linaro.org) X-ZM-MESSAGEID: 1663578798990100009 Content-Type: text/plain; charset="utf-8" The FF-A specification defines framework messages sent as direct requests when certain events occurs. For instance when a VM (guest) is created or destroyed. Only SPs which have subscribed to these events will receive them. An SP can subscribe to these messages in its partition properties. The partition properties of each SP is retrieved with FFA_PARTITION_INFO_GET which returns the information in our RX buffer. Using FFA_PARTITION_INFO_GET changes the owner of the RX buffer to the caller (us), so once we're done with the buffer it must be released using FFA_RX_RELEASE before another call can be made. Signed-off-by: Jens Wiklander --- xen/arch/arm/ffa.c | 192 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 191 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/ffa.c b/xen/arch/arm/ffa.c index 8cb5c829a394..1e94113b20bd 100644 --- a/xen/arch/arm/ffa.c +++ b/xen/arch/arm/ffa.c @@ -187,6 +187,14 @@ #define FFA_MSG_SEND 0x8400006EU #define FFA_MSG_POLL 0x8400006AU =20 +/* Partition information descriptor */ +struct ffa_partition_info_1_1 { + uint16_t id; + uint16_t execution_context; + uint32_t partition_properties; + uint8_t uuid[16]; +}; + struct ffa_ctx { uint32_t guest_vers; bool interrupted; @@ -195,6 +203,12 @@ struct ffa_ctx { /* Negotiated FF-A version to use with the SPMC */ static uint32_t ffa_version __ro_after_init; =20 +/* SPs subscribing to VM_CREATE and VM_DESTROYED events */ +static uint16_t *subscr_vm_created __read_mostly; +static unsigned int subscr_vm_created_count __read_mostly; +static uint16_t *subscr_vm_destroyed __read_mostly; +static unsigned int subscr_vm_destroyed_count __read_mostly; + /* * Our rx/tx buffers shared with the SPMC. * @@ -284,6 +298,72 @@ static int32_t ffa_rxtx_map(register_t tx_addr, regist= er_t rx_addr, return ffa_simple_call(fid, tx_addr, rx_addr, page_count, 0); } =20 +static int32_t ffa_partition_info_get(uint32_t w1, uint32_t w2, uint32_t w= 3, + uint32_t w4, uint32_t w5, + uint32_t *count) +{ + const struct arm_smccc_1_2_regs arg =3D { + .a0 =3D FFA_PARTITION_INFO_GET, + .a1 =3D w1, + .a2 =3D w2, + .a3 =3D w3, + .a4 =3D w4, + .a5 =3D w5, + }; + struct arm_smccc_1_2_regs resp; + uint32_t ret; + + arm_smccc_1_2_smc(&arg, &resp); + + ret =3D get_ffa_ret_code(&resp); + if ( !ret ) + *count =3D resp.a2; + + return ret; +} + +static int32_t ffa_rx_release(void) +{ + return ffa_simple_call(FFA_RX_RELEASE, 0, 0, 0, 0); +} + +static int32_t ffa_direct_req_send_vm(uint16_t sp_id, uint16_t vm_id, + uint8_t msg) +{ + uint32_t exp_resp =3D FFA_MSG_FLAG_FRAMEWORK; + int32_t res; + + if ( msg =3D=3D FFA_MSG_SEND_VM_CREATED ) + exp_resp |=3D FFA_MSG_RESP_VM_CREATED; + else if ( msg =3D=3D FFA_MSG_SEND_VM_DESTROYED ) + exp_resp |=3D FFA_MSG_RESP_VM_DESTROYED; + else + return FFA_RET_INVALID_PARAMETERS; + + do { + const struct arm_smccc_1_2_regs arg =3D { + .a0 =3D FFA_MSG_SEND_DIRECT_REQ_32, + .a1 =3D sp_id, + .a2 =3D FFA_MSG_FLAG_FRAMEWORK | msg, + .a5 =3D vm_id, + }; + struct arm_smccc_1_2_regs resp; + + arm_smccc_1_2_smc(&arg, &resp); + if ( resp.a0 !=3D FFA_MSG_SEND_DIRECT_RESP_32 || resp.a2 !=3D exp_= resp ) + { + /* + * This is an invalid response, likely due to some error in the + * implementation of the ABI. + */ + return FFA_RET_INVALID_PARAMETERS; + } + res =3D resp.a3; + } while ( res =3D=3D FFA_RET_INTERRUPTED || res =3D=3D FFA_RET_RETRY ); + + return res; +} + static u16 get_vm_id(const struct domain *d) { /* +1 since 0 is reserved for the hypervisor in FF-A */ @@ -431,6 +511,10 @@ uint32_t ffa_get_call_count(void) int ffa_domain_init(struct domain *d, uint32_t flags) { struct ffa_ctx *ctx; + unsigned int n; + unsigned int m; + unsigned int c_pos; + int32_t res; =20 if ( !ffa_version || !(flags & XEN_ARM_FLAGS_FFA) ) return -ENODEV; @@ -439,19 +523,54 @@ int ffa_domain_init(struct domain *d, uint32_t flags) if ( !ctx ) return -ENOMEM; =20 + for ( n =3D 0; n < subscr_vm_created_count; n++ ) + { + res =3D ffa_direct_req_send_vm(subscr_vm_created[n], get_vm_id(d), + FFA_MSG_SEND_VM_CREATED); + if ( res ) + { + printk(XENLOG_ERR "ffa: Failed to report creation of vm_id %u = to %u: res %d\n", + get_vm_id(d), subscr_vm_created[n], res); + c_pos =3D n; + goto err; + } + } + d->arch.ffa =3D ctx; =20 return 0; + +err: + /* Undo any already sent vm created messaged */ + for ( n =3D 0; n < c_pos; n++ ) + for ( m =3D 0; m < subscr_vm_destroyed_count; m++ ) + if ( subscr_vm_destroyed[m] =3D=3D subscr_vm_created[n] ) + ffa_direct_req_send_vm(subscr_vm_destroyed[n], get_vm_id(d= ), + FFA_MSG_SEND_VM_DESTROYED); + + return -ENOMEM; } =20 /* This function is supposed to undo what ffa_domain_init() has done */ void ffa_domain_destroy(struct domain *d) { struct ffa_ctx *ctx =3D d->arch.ffa; + unsigned int n; + int32_t res; =20 if ( !ctx ) return; =20 + for ( n =3D 0; n < subscr_vm_destroyed_count; n++ ) + { + res =3D ffa_direct_req_send_vm(subscr_vm_destroyed[n], get_vm_id(d= ), + FFA_MSG_SEND_VM_DESTROYED); + + if ( res ) + printk(XENLOG_ERR "ffa: Failed to report destruction of vm_id = %u to %u: res %d\n", + get_vm_id(d), subscr_vm_destroyed[n], res); + } + XFREE(d->arch.ffa); } =20 @@ -464,6 +583,68 @@ int ffa_relinquish_resources(struct domain *d) return 0; } =20 +static bool __init init_subscribers(void) +{ + struct ffa_partition_info_1_1 *fpi; + bool ret =3D false; + uint32_t count; + int e; + uint32_t n; + uint32_t c_pos; + uint32_t d_pos; + + if ( ffa_version < FFA_VERSION_1_1 ) + return true; + + e =3D ffa_partition_info_get(0, 0, 0, 0, 0, &count); + if ( e ) + { + printk(XENLOG_ERR "ffa: Failed to get list of SPs: %d\n", e); + goto out; + } + + fpi =3D ffa_rx; + subscr_vm_created_count =3D 0; + subscr_vm_destroyed_count =3D 0; + for ( n =3D 0; n < count; n++ ) + { + if (fpi[n].partition_properties & FFA_PART_PROP_NOTIF_CREATED) + subscr_vm_created_count++; + if (fpi[n].partition_properties & FFA_PART_PROP_NOTIF_DESTROYED) + subscr_vm_destroyed_count++; + } + + if ( subscr_vm_created_count ) + subscr_vm_created =3D xzalloc_array(uint16_t, subscr_vm_created_co= unt); + if ( subscr_vm_destroyed_count ) + subscr_vm_destroyed =3D xzalloc_array(uint16_t, + subscr_vm_destroyed_count); + if ( (subscr_vm_created_count && !subscr_vm_created) || + (subscr_vm_destroyed_count && !subscr_vm_destroyed) ) + { + printk(XENLOG_ERR "ffa: Failed to allocate subscription lists\n"); + subscr_vm_created_count =3D 0; + subscr_vm_destroyed_count =3D 0; + XFREE(subscr_vm_created); + XFREE(subscr_vm_destroyed); + goto out; + } + + for ( c_pos =3D 0, d_pos =3D 0, n =3D 0; n < count; n++ ) + { + if ( fpi[n].partition_properties & FFA_PART_PROP_NOTIF_CREATED ) + subscr_vm_created[c_pos++] =3D fpi[n].id; + if ( fpi[n].partition_properties & FFA_PART_PROP_NOTIF_DESTROYED ) + subscr_vm_destroyed[d_pos++] =3D fpi[n].id; + } + + ret =3D true; +out: + ffa_rx_release(); + + return ret; +} + static int __init ffa_init(void) { uint32_t vers; @@ -505,9 +686,11 @@ static int __init ffa_init(void) printk(XENLOG_INFO "ARM FF-A Firmware version %u.%u\n", major_vers, minor_vers); =20 - if ( + if ( !check_mandatory_feature(FFA_PARTITION_INFO_GET) || + !check_mandatory_feature(FFA_RX_RELEASE) || #ifdef CONFIG_ARM_64 !check_mandatory_feature(FFA_RXTX_MAP_64) || + !check_mandatory_feature(FFA_MEM_SHARE_64) || #endif #ifdef CONFIG_ARM_32 !check_mandatory_feature(FFA_RXTX_MAP_32) || @@ -533,6 +716,9 @@ static int __init ffa_init(void) ffa_page_count =3D 1; ffa_version =3D vers; =20 + if ( !init_subscribers() ) + goto err_free_ffa_tx; + return 0; =20 err_free_ffa_tx: @@ -543,6 +729,10 @@ err_free_ffa_rx: ffa_rx =3D NULL; ffa_page_count =3D 0; ffa_version =3D 0; + XFREE(subscr_vm_created); + subscr_vm_created_count =3D 0; + XFREE(subscr_vm_destroyed); + subscr_vm_destroyed_count =3D 0; =20 return 0; } --=20 2.31.1