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

[RFC PATCH v1 11/26] xen/arm/cca: terminate and destroy Realms on relinquish


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Koichiro Den <den@xxxxxxxxxxxxx>
  • Date: Fri, 15 May 2026 13:07:57 +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=/bHYT6atPOeZOv2k1L5q3pwz1qEMb9cMvUWztfWVSOo=; b=f6oC0cn/u8yXC7n94q+pGMj7xn5ahLQ9biNhMhxNZArow95r2utq6Ne5iZvRTN7kIItFDK5h/F2bDFTbM5wEgvHXL/fAb/JH52/ILCWzbQh7SzmtSXdGaL0ULUiy0bjXD/ORILAev2K84bAAYd6Jl3DCo/3lOPXHl1fQvJG8XyvdS0EWnYV2OmmxPiyZ0PFSXI3rrWIyfln4XzSJDcRuT+4lr21oF9gyndrYXWJomuhxwPX9fnn3d02sh2UEdzXrFfXXOknRPidfwDJ9QwYrVECv0n5P/Zfini5v0AAlQo1WxQXsU9/V7Kp8LWjG/EFnxeBelZF8aC3nt0PhNWn4aw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=HqMeKL6+t5HTfD1sFnJcQa1xL8qOZZ4tMOVV/GkOhttW0nhD7i6sh2z94Gy9GTuGYTHQkcCCPyECQo/vLDUN2ivUliB56axWIPsPAVL43Az1E6ox5pHVu7hBC58OoUhk3oIuzla6ofmTRxpc5T6JJqYl0i3elVFXebLc/u9cpLPvwMZMZ+Ie1502kfjJjzkQd50GnBI8k9hZ8EHXeqIGIypZJ3QmnIvA4IoAO46HcN0rXSj1DOTpM9EDWQsTs9d/b3g+Y1sGwuDxBPl+HsFZ5BDju+B3QV72AG5vVhjpjShu47PiG8LiZ36MPgiss3BFW+S6UJqtlUiZ7S130uMvQw==
  • 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:33 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Run Realm termination and destruction from the relinquish path. Keep the
metadata until RMM ownership has really ended.

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

diff --git a/xen/arch/arm/cca/state.c b/xen/arch/arm/cca/state.c
index 3646948eb11c..e58e261265f3 100644
--- a/xen/arch/arm/cca/state.c
+++ b/xen/arch/arm/cca/state.c
@@ -3,10 +3,12 @@
 #include <xen/lib.h>
 #include <xen/mm.h>
 #include <xen/sched.h>
+#include <xen/xmalloc.h>
 
 #include <asm/cca.h>
 
 #include "rmi.h"
+#include "sro.h"
 
 static void arm_cca_reset_domain_state(struct domain *d)
 {
@@ -24,6 +26,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.realm_terminate_done = false;
 
     for ( i = 0; i < ARRAY_SIZE(d->arch.cca.realm_sro_pages); ++i )
         d->arch.cca.realm_sro_pages[i] = NULL;
@@ -48,8 +51,20 @@ void arm_cca_domain_init(struct domain *d)
     arm_cca_reset_domain_state(d);
 }
 
+static void arm_cca_domain_free_metadata(struct domain *d)
+{
+    xfree(d->arch.cca.data_pages);
+    xfree(d->arch.cca.rtts);
+}
+
+/*
+ * RMI teardown is returnable and runs from
+ * arm_cca_domain_relinquish_resources().  The final domain hook only releases
+ * metadata if an earlier setup path left it behind.
+ */
 void arm_cca_domain_destroy(struct domain *d)
 {
+    arm_cca_domain_free_metadata(d);
     arm_cca_reset_domain_state(d);
 }
 
@@ -71,9 +86,111 @@ static int arm_cca_relinquish_abandoned_pages(struct domain 
*d)
     return 0;
 }
 
+static int arm_cca_rmi_realm_destroy_complete(struct domain *d)
+{
+    struct arm_cca_sro_mem_xfer xfer = {
+        .pages = d->arch.cca.realm_sro_pages,
+        .nr_pages = &d->arch.cca.nr_realm_sro_pages,
+        .abandoned_pages = &d->arch.cca.abandoned_pages,
+    };
+    struct arm_smccc_res res;
+    int rc;
+
+    rc = arm_cca_rmi_realm_destroy(d->arch.cca.rd, &res);
+    rc = arm_cca_sro_complete_mem_transfer(rc, &res, &xfer);
+    if ( rc == 0 && d->arch.cca.nr_realm_sro_pages != 0 )
+        rc = -EIO;
+
+    return rc;
+}
+
+static int arm_cca_terminate_realm(struct domain *d)
+{
+    struct arm_smccc_res res;
+    int rc;
+
+    if ( d->arch.cca.rd == INVALID_PADDR || d->arch.cca.realm_terminate_done )
+        return 0;
+
+    /*
+     * DEN0137 2.0-bet1 - D1.2.5 starts Realm destruction by terminating the
+     * Realm.  Remember success because later host-side undelegation may fail
+     * and force a retry.
+     */
+    rc = arm_cca_rmi_realm_terminate(d->arch.cca.rd, &res);
+    if ( rc != 0 )
+        return rc;
+
+    d->arch.cca.realm_terminate_done = true;
+
+    return 0;
+}
+
+static int arm_cca_destroy_realm(struct domain *d)
+{
+    int rc;
+
+    if ( d->arch.cca.rd != INVALID_PADDR )
+    {
+        rc = arm_cca_rmi_realm_destroy_complete(d);
+        if ( rc != 0 )
+            return rc;
+
+        d->arch.cca.rd = INVALID_PADDR;
+        d->arch.cca.realm_active = false;
+    }
+
+    if ( d->arch.cca.rtt_root_page )
+    {
+        rc = arm_cca_undelegate_granule(
+            page_to_maddr(d->arch.cca.rtt_root_page));
+        if ( rc != 0 )
+            return rc;
+
+        free_domheap_page(d->arch.cca.rtt_root_page);
+        d->arch.cca.rtt_root_page = NULL;
+    }
+
+    if ( d->arch.cca.rd_page )
+    {
+        rc = arm_cca_undelegate_granule(page_to_maddr(d->arch.cca.rd_page));
+        if ( rc != 0 )
+            return rc;
+
+        free_domheap_page(d->arch.cca.rd_page);
+        d->arch.cca.rd_page = NULL;
+    }
+
+    return 0;
+}
+
+/*
+ * DEN0137 2.0-bet1 - D1.2.5 Realm destruction flow.
+ *
+ * RMI teardown runs in the returnable relinquish path so Xen can retry
+ * incomplete destruction and avoid resource leaks.  Realm-associated objects
+ * can be destroyed in any order.
+ */
 int arm_cca_domain_relinquish_resources(struct domain *d)
 {
-    return arm_cca_relinquish_abandoned_pages(d);
+    int rc;
+
+    rc = arm_cca_terminate_realm(d);
+    if ( rc != 0 )
+        return rc;
+
+    rc = arm_cca_destroy_realm(d);
+    if ( rc != 0 )
+        return rc;
+
+    rc = arm_cca_relinquish_abandoned_pages(d);
+    if ( rc != 0 )
+        return rc;
+
+    arm_cca_domain_free_metadata(d);
+    arm_cca_reset_domain_state(d);
+
+    return 0;
 }
 
 void arm_cca_vcpu_init(struct vcpu *v)
diff --git a/xen/arch/arm/include/asm/cca.h b/xen/arch/arm/include/asm/cca.h
index 9b53c80b5bba..b135dd176751 100644
--- a/xen/arch/arm/include/asm/cca.h
+++ b/xen/arch/arm/include/asm/cca.h
@@ -66,6 +66,9 @@ struct arm_cca_domain_state {
 
     struct arm_cca_data_page_record *data_pages;
     unsigned long nr_data_pages;
+
+    /* Realm destruction state for domain_relinquish_resources(). */
+    bool realm_terminate_done;
 };
 
 struct arm_cca_vcpu_state {
-- 
2.51.0




 


Rackspace

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