[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC PATCH v1 12/26] xen/arm/cca: tear down Realm DATA and RTT granules


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Koichiro Den <den@xxxxxxxxxxxxx>
  • Date: Fri, 15 May 2026 13:07:58 +0900
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=valinux.co.jp; dmarc=pass action=none header.from=valinux.co.jp; dkim=pass header.d=valinux.co.jp; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=nR9DiFmmPQZJPSPKu4GBPDG2fdbX8kmCXfKAod/+QeY=; b=VFs3f8WtuM2ad+k1nVQSQ3Vf/SZfhc8W+5Nimc6j+Zya2ZcoHqoE91r0KJ2Y8V9LhUSm8EaTAdJEwtUFUXFLNVhAGR0XMTxZoLgb3MjmkroFXV9YdTQwYgCcYK3PkA91WF/KBq1N0F1Fq/Hh8kQ4uS75dPZMK7hjxaZkXeX+AkURNRGOY11QYxyqTYUlVt0rGdnaypORDrE1NSYuXHCQheJRAmXVr1tYImrXt4TLtKGsrMl7Qsm287kQPE04bQNDw9TBQZUaMWO2nOqFibsJh988Nt7vrqyQx/6cX04CDu9WU5kl12142BEy7FCBF/HCkMM0l44WupByrHpNwmKGaw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=ADdA8lA+st7vdzuVbZ6B8RfzwI9Nj9yXkNnkeUN86DSaagZDbscBYPZ/5CspMyWT4ErNCPCzWMoDKVE3YbsQg921+4A9tKJ1RHwF9dQ3586tjjQvMOV7GYQNc74GEFwed3G7X9hJFyPKewC3yhwDZhXlw1vNjGKgwXct/3sBmhmpT1A5PcUBzG3T22v77tdo187Cq5OGn+ZKLfQkA+oSkr4cQLOmTZL+/CpzpMwMBN8lSeNRpA+wrWuJIP6gWSuldRfBGGdNgZEcwkU3rVXW1UrW1iIpNYF5fPBJJlsyzVkVgK7Lj/ftGIvZqKwYFymZAR4kjyhtJeLqqn0MVaH3TQ==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=valinux.co.jp header.i="@valinux.co.jp" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=valinux.co.jp;
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Anthony PERARD <anthony.perard@xxxxxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Julien Grall <julien@xxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, "Daniel P. Smith" <dpsmith@xxxxxxxxxxxxxxxxxxxx>, Juergen Gross <jgross@xxxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Fri, 15 May 2026 04:12:35 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Tear down mapped DATA granules and the RTT hierarchy before returning
the backing pages to Xen.

Signed-off-by: Koichiro Den <den@xxxxxxxxxxxxx>
---
 xen/arch/arm/cca/state.c       | 151 +++++++++++++++++++++++++++++++++
 xen/arch/arm/include/asm/cca.h |   1 +
 2 files changed, 152 insertions(+)

diff --git a/xen/arch/arm/cca/state.c b/xen/arch/arm/cca/state.c
index e58e261265f3..c85ef56a1297 100644
--- a/xen/arch/arm/cca/state.c
+++ b/xen/arch/arm/cca/state.c
@@ -1,15 +1,19 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 
+#include <xen/errno.h>
 #include <xen/lib.h>
 #include <xen/mm.h>
 #include <xen/sched.h>
 #include <xen/xmalloc.h>
 
 #include <asm/cca.h>
+#include <asm/event.h>
 
 #include "rmi.h"
 #include "sro.h"
 
+#define ARM_CCA_RTT_DATA_UNMAP_BATCH 1024UL
+
 static void arm_cca_reset_domain_state(struct domain *d)
 {
     unsigned int i;
@@ -26,6 +30,7 @@ static void arm_cca_reset_domain_state(struct domain *d)
     d->arch.cca.nr_rtts = 0;
     d->arch.cca.data_pages = NULL;
     d->arch.cca.nr_data_pages = 0;
+    d->arch.cca.relinquish_data_idx = 0;
     d->arch.cca.realm_terminate_done = false;
 
     for ( i = 0; i < ARRAY_SIZE(d->arch.cca.realm_sro_pages); ++i )
@@ -51,6 +56,37 @@ void arm_cca_domain_init(struct domain *d)
     arm_cca_reset_domain_state(d);
 }
 
+static int
+arm_cca_rtt_data_unmap_4k(paddr_t rd,
+                          const struct arm_cca_data_page_record *rec)
+{
+    struct arm_smccc_res res;
+    paddr_t top = rec->ipa + PAGE_SIZE;
+    uint64_t desc;
+    int rc;
+
+    /*
+     * DEN0137 2.0-bet1 marks SINGLE oaddr as SBZ, and TF-RMM does not use it,
+     * so keep X5 zero here.
+     */
+    rc = arm_cca_rmi_rtt_data_unmap(rd, rec->ipa, top,
+                                    ARM_CCA_RMI_ADDR_TYPE_SINGLE, 0, &res);
+    if ( rc != 0 )
+        return rc;
+
+    desc = res.a2;
+
+    if ( res.a1 != top ||
+         arm_cca_rmi_addr_desc_4k_pa(desc) != rec->pa ||
+         arm_cca_rmi_addr_desc_4k_size(desc) != ARM_CCA_RMI_PAGE_L3 ||
+         arm_cca_rmi_addr_desc_4k_count(desc) != 1 ||
+         arm_cca_rmi_addr_desc_4k_state(desc) !=
+         ARM_CCA_RMI_OP_MEM_DELEGATED )
+        return -EIO;
+
+    return 0;
+}
+
 static void arm_cca_domain_free_metadata(struct domain *d)
 {
     xfree(d->arch.cca.data_pages);
@@ -104,6 +140,68 @@ static int arm_cca_rmi_realm_destroy_complete(struct 
domain *d)
     return rc;
 }
 
+static int arm_cca_teardown_data_pages(struct domain *d)
+{
+    unsigned long i;
+    int rc;
+
+    if ( !d->arch.cca.data_pages )
+        return 0;
+
+    for ( i = d->arch.cca.relinquish_data_idx;
+          i < d->arch.cca.nr_data_pages; ++i )
+    {
+        struct arm_cca_data_page_record *rec = &d->arch.cca.data_pages[i];
+
+        if ( rec->pa == INVALID_PADDR )
+            continue;
+
+        if ( rec->ipa != INVALID_PADDR )
+        {
+            if ( d->arch.cca.rd == INVALID_PADDR )
+                return -EIO;
+
+            rc = arm_cca_rtt_data_unmap_4k(d->arch.cca.rd, rec);
+            if ( rc != 0 )
+            {
+                d->arch.cca.relinquish_data_idx = i;
+                return rc;
+            }
+
+            /*
+             * The RTTE no longer owns this DATA granule.  Keep rec->pa so a
+             * later retry can finish the host-side undelegation.
+             */
+            rec->ipa = INVALID_PADDR;
+        }
+
+        rc = arm_cca_undelegate_granule(rec->pa);
+        if ( rc != 0 )
+        {
+            d->arch.cca.relinquish_data_idx = i;
+            return rc;
+        }
+
+        /*
+         * The page remains owned by the domain and on d->page_list so the
+         * generic relinquish path can free it later.
+         */
+        rec->pa = INVALID_PADDR;
+
+        if ( ((i + 1) % ARM_CCA_RTT_DATA_UNMAP_BATCH) == 0 &&
+             hypercall_preempt_check() )
+        {
+            d->arch.cca.relinquish_data_idx = i + 1;
+            return -ERESTART;
+        }
+    }
+
+    d->arch.cca.nr_data_pages = 0;
+    d->arch.cca.relinquish_data_idx = 0;
+
+    return 0;
+}
+
 static int arm_cca_terminate_realm(struct domain *d)
 {
     struct arm_smccc_res res;
@@ -126,6 +224,51 @@ static int arm_cca_terminate_realm(struct domain *d)
     return 0;
 }
 
+static int arm_cca_teardown_rtts(struct domain *d)
+{
+    struct arm_smccc_res res;
+    int rc;
+
+    while ( d->arch.cca.nr_rtts != 0 )
+    {
+        struct arm_cca_rtt_record *rec =
+            &d->arch.cca.rtts[d->arch.cca.nr_rtts - 1];
+
+        if ( rec->pa == INVALID_PADDR )
+        {
+            d->arch.cca.nr_rtts--;
+            continue;
+        }
+
+        if ( rec->ipa != INVALID_PADDR )
+        {
+            if ( d->arch.cca.rd == INVALID_PADDR )
+                return -EIO;
+
+            rc = arm_cca_rmi_rtt_destroy(d->arch.cca.rd, rec->ipa,
+                                         rec->level, &res);
+            if ( rc != 0 )
+                return rc;
+
+            /*
+             * The RMM object is gone.  Keep rec->pa so a later retry can
+             * finish the host-side undelegation.
+             */
+            rec->ipa = INVALID_PADDR;
+        }
+
+        rc = arm_cca_undelegate_granule(rec->pa);
+        if ( rc != 0 )
+            return rc;
+
+        free_domheap_page(maddr_to_page(rec->pa));
+        rec->pa = INVALID_PADDR;
+        d->arch.cca.nr_rtts--;
+    }
+
+    return 0;
+}
+
 static int arm_cca_destroy_realm(struct domain *d)
 {
     int rc;
@@ -179,6 +322,14 @@ int arm_cca_domain_relinquish_resources(struct domain *d)
     if ( rc != 0 )
         return rc;
 
+    rc = arm_cca_teardown_data_pages(d);
+    if ( rc != 0 )
+        return rc;
+
+    rc = arm_cca_teardown_rtts(d);
+    if ( rc != 0 )
+        return rc;
+
     rc = arm_cca_destroy_realm(d);
     if ( rc != 0 )
         return rc;
diff --git a/xen/arch/arm/include/asm/cca.h b/xen/arch/arm/include/asm/cca.h
index b135dd176751..d69e95a10010 100644
--- a/xen/arch/arm/include/asm/cca.h
+++ b/xen/arch/arm/include/asm/cca.h
@@ -68,6 +68,7 @@ struct arm_cca_domain_state {
     unsigned long nr_data_pages;
 
     /* Realm destruction state for domain_relinquish_resources(). */
+    unsigned long relinquish_data_idx;
     bool realm_terminate_done;
 };
 
-- 
2.51.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.