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