|
[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
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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |