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

[RFC PATCH v1 07/26] xen/arm/cca: initialize the RMM and Realm parameters


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Koichiro Den <den@xxxxxxxxxxxxx>
  • Date: Fri, 15 May 2026 13:07:53 +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=UyVaj4/RdCO+bvx/q4AkK7MGTGIPg9kj2o0tPGAL1DI=; b=hyf6QhfhCW+gdEw+ZDn7DCP9gbwlZ9igPTbtGgiEAhErLHGq9Dwdv3l95FPMZOlHcDxap66Rnp2dYFkHQRvnGa44eSlgYB6NCC4IoVnJceZ3CV/j/A2Glx0Njl58IjtKwXUUwH5w63NRrhnEBf96w9IoKd4gfg9Vcb5cDMB/qpcW6N4/hmBI6PgI2jyHdp5ZogzCHLbkZVwVKHXRl91g/ok3zcthx7WRr7Snz87M3aPBoxyNzWEWhY/kZYFmMWEPzBaUFtqZbzGKV/0B//nMGnn9AzmN3BsZPSsgzgFhICxFC8CZOaH9eTBsEwx3U2DiyelTAnmhY0cq1TEscDobAw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=QDCrjOBeD+nbUqtSUUKMu9l68x2JF7jrM5YO8hH5Am7A/xW/zbyy3TVpPiq6Za/S57zBbhRxkNm3kVwwbPgzLcrnTbapOzV7bHPaEbvD/j7j6ow12ueyC3RJcpf1aCBJLqaIsTEFuZLgozh78XzYxZrh3VsmVNm8jclhFoc5ik8p/hDxWRiHIsfr7m4sdEPKuralTwAHUSTulwJ34osQ2MbdL8R7/IYY0obnSo/YWsu/G140cIsjkfAg5UFZqVMAkAJpQ8lD8HTOheokXhdpdPUVK1KZd/CYXcJopY6Qd63F5tr3LU4fjDcm1oCxC/Y0AashRrC6XoC2EIpRZoUl0g==
  • 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:08:39 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Activate the RMM during Xen init and keep the small Realm/REC parameter
initializers with the rest of the CCA code.

Signed-off-by: Koichiro Den <den@xxxxxxxxxxxxx>
---
 xen/arch/arm/cca/Makefile      |   1 +
 xen/arch/arm/cca/realm.c       | 191 +++++++++++++++++++++++++++++++++
 xen/arch/arm/include/asm/cca.h |  10 ++
 3 files changed, 202 insertions(+)
 create mode 100644 xen/arch/arm/cca/realm.c

diff --git a/xen/arch/arm/cca/Makefile b/xen/arch/arm/cca/Makefile
index 7f20d43323c3..57c3986d5de8 100644
--- a/xen/arch/arm/cca/Makefile
+++ b/xen/arch/arm/cca/Makefile
@@ -1,3 +1,4 @@
 obj-y += granule.o
+obj-y += realm.o
 obj-y += rmi.o
 obj-y += state.o
diff --git a/xen/arch/arm/cca/realm.c b/xen/arch/arm/cca/realm.c
new file mode 100644
index 000000000000..14aa7bba595f
--- /dev/null
+++ b/xen/arch/arm/cca/realm.c
@@ -0,0 +1,191 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <xen/errno.h>
+#include <xen/init.h>
+#include <xen/lib.h>
+#include <xen/mm.h>
+#include <xen/sched.h>
+
+#include <asm/cca.h>
+
+#include "rmi.h"
+#include "sro.h"
+
+/*
+ * Pages donated while activating the RMM are owned by the activated RMM until
+ * system reset.  Keep the host references here to make that lifetime explicit.
+ */
+static struct page_info *arm_cca_rmm_sro_pages[ARM_CCA_MAX_SRO_DONATION_PAGES];
+static unsigned int arm_cca_nr_rmm_sro_pages;
+static struct page_list_head arm_cca_rmm_abandoned_pages =
+    PAGE_LIST_HEAD_INIT(arm_cca_rmm_abandoned_pages);
+static bool arm_cca_rmm_available;
+static unsigned long arm_cca_rmm_features0;
+static unsigned long arm_cca_rmm_features1;
+
+static int arm_cca_set_rmm_config(struct arm_cca_rmi_rmm_config *cfg)
+{
+    memset(cfg, 0, ARM_CCA_RMI_RMM_CONFIG_SIZE);
+    cfg->rmi_granule_size = ARM_CCA_RMI_GRANULE_SIZE_4KB;
+    cfg->tracking_region_size = ARM_CCA_RMI_TRACKING_4KB_REGION_1GB;
+
+    return arm_cca_rmi_rmm_config_set(virt_to_maddr(cfg));
+}
+
+static int arm_cca_activate_rmm(void)
+{
+    struct arm_cca_rmi_rmm_config *cfg;
+    struct arm_cca_sro_mem_xfer xfer = {
+        .pages = arm_cca_rmm_sro_pages,
+        .nr_pages = &arm_cca_nr_rmm_sro_pages,
+        .max_pages = ARRAY_SIZE(arm_cca_rmm_sro_pages),
+        .abandoned_pages = &arm_cca_rmm_abandoned_pages,
+    };
+    struct arm_smccc_res res;
+    int rc = 0;
+
+    cfg = alloc_xenheap_page();
+    if ( cfg == NULL )
+        return -ENOMEM;
+
+    rc = arm_cca_set_rmm_config(cfg);
+    if ( rc == 0 )
+    {
+        rc = arm_cca_rmi_rmm_activate(&res);
+        rc = arm_cca_sro_complete_mem_transfer(rc, &res, &xfer);
+    }
+
+    if ( rc != 0 && (arm_cca_nr_rmm_sro_pages != 0 ||
+                     !page_list_empty(&arm_cca_rmm_abandoned_pages)) )
+        rc = -EIO;
+
+    free_xenheap_page(cfg);
+
+    return rc;
+}
+
+static int arm_cca_validate_rmm_config(void)
+{
+    struct arm_cca_rmi_rmm_config *cfg;
+    struct arm_smccc_res res;
+    int rc;
+
+    cfg = alloc_xenheap_page();
+    if ( cfg == NULL )
+        return -ENOMEM;
+
+    memset(cfg, 0, ARM_CCA_RMI_RMM_CONFIG_SIZE);
+
+    rc = arm_cca_rmi_rmm_config_get(virt_to_maddr(cfg), &res);
+    if ( rc != 0 )
+    {
+        printk(XENLOG_ERR
+               "ARM CCA: RMI_RMM_CONFIG_GET failed status=%#x data=%#lx\n",
+               arm_cca_rmi_status_code(arm_cca_rmi_result(&res)),
+               (unsigned long)arm_cca_rmi_result_data(
+                   arm_cca_rmi_result(&res)));
+        rc = -EOPNOTSUPP;
+        goto out;
+    }
+
+    /*
+     * Xen's current Realm build and teardown paths assume 4KB RMI granules
+     * and the matching 1GB tracking region.  Other active RMM configurations
+     * are valid RMI, but need explicit Xen support before they can be
+     * accepted here.
+     */
+    if ( cfg->rmi_granule_size != ARM_CCA_RMI_GRANULE_SIZE_4KB )
+    {
+        printk(XENLOG_ERR
+               "ARM CCA: requires 4KB RMI granules, but current RMM "
+               "granule size encoding is %u\n", cfg->rmi_granule_size);
+        rc = -EOPNOTSUPP;
+        goto out;
+    }
+
+    if ( cfg->tracking_region_size != ARM_CCA_RMI_TRACKING_4KB_REGION_1GB )
+    {
+        printk(XENLOG_ERR
+               "ARM CCA: requires 1GB tracking regions for 4KB RMI "
+               "granules, but current RMM tracking-region encoding is %u\n",
+               cfg->tracking_region_size);
+        rc = -EOPNOTSUPP;
+        goto out;
+    }
+
+    rc = 0;
+
+out:
+    free_xenheap_page(cfg);
+
+    return rc;
+}
+
+static int __init arm_cca_init_rmi(void)
+{
+    unsigned long revision_lower;
+    int rc;
+
+    rc = arm_cca_rmi_version(ARM_CCA_RMI_ABI_VERSION, &revision_lower, NULL);
+    if ( rc != 0 || revision_lower != ARM_CCA_RMI_ABI_VERSION )
+        return 0;
+
+    arm_cca_rmm_features0 = arm_cca_rmi_features(0);
+    arm_cca_rmm_features1 = arm_cca_rmi_features(1);
+
+    rc = arm_cca_activate_rmm();
+    if ( rc != 0 )
+    {
+        printk(XENLOG_ERR "ARM CCA: RMM activate failed: %d\n", rc);
+        return 0;
+    }
+
+    rc = arm_cca_validate_rmm_config();
+    if ( rc != 0 )
+        return 0;
+
+    rc = arm_cca_prepare_host_memory(arm_cca_rmm_features1);
+    if ( rc != 0 )
+    {
+        printk(XENLOG_ERR "ARM CCA: host memory metadata check failed: %d\n",
+               rc);
+        return 0;
+    }
+
+    arm_cca_rmm_available = true;
+    printk(XENLOG_INFO "ARM CCA: RMI configured\n");
+
+    return 0;
+}
+__initcall(arm_cca_init_rmi);
+
+int arm_cca_probe(struct domain *d)
+{
+    if ( !arm_cca_rmm_available )
+        return -EOPNOTSUPP;
+
+    d->arch.cca.rmi_features0 = arm_cca_rmm_features0;
+    d->arch.cca.rmi_features1 = arm_cca_rmm_features1;
+
+    return 0;
+}
+
+void arm_cca_realm_params_init(struct arm_cca_rmi_realm_params *params)
+{
+    memset(params, 0, sizeof(*params));
+}
+
+void arm_cca_rec_params_init(struct arm_cca_rmi_rec_params *params,
+                             register_t mpidr, register_t pc, bool runnable)
+{
+    memset(params, 0, sizeof(*params));
+
+    params->flags = runnable ? ARM_CCA_RMI_REC_CREATE_RUNNABLE : 0;
+    params->mpidr = mpidr;
+    params->pc = pc;
+}
+
+void arm_cca_rec_run_init(struct arm_cca_rmi_rec_run *run)
+{
+    memset(run, 0, sizeof(*run));
+}
diff --git a/xen/arch/arm/include/asm/cca.h b/xen/arch/arm/include/asm/cca.h
index c35d51f750a3..80c161078d6c 100644
--- a/xen/arch/arm/include/asm/cca.h
+++ b/xen/arch/arm/include/asm/cca.h
@@ -24,6 +24,9 @@
 
 struct domain;
 struct vcpu;
+struct arm_cca_rmi_realm_params;
+struct arm_cca_rmi_rec_params;
+struct arm_cca_rmi_rec_run;
 struct page_info;
 
 struct arm_cca_rtt_record {
@@ -84,4 +87,11 @@ int arm_cca_delegate_granule(paddr_t granule);
 int arm_cca_undelegate_granule(paddr_t granule);
 int arm_cca_prepare_host_memory(unsigned long features1) __init;
 
+int arm_cca_probe(struct domain *d);
+
+void arm_cca_realm_params_init(struct arm_cca_rmi_realm_params *params);
+void arm_cca_rec_params_init(struct arm_cca_rmi_rec_params *params,
+                             register_t mpidr, register_t pc, bool runnable);
+void arm_cca_rec_run_init(struct arm_cca_rmi_rec_run *run);
+
 #endif /* ARM_CCA_H */
-- 
2.51.0




 


Rackspace

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