|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] arm/mpu: Introduce `v8r_el1_msa` device tree property for domains
commit 1afacf7b153763ee9c8a7a2ded1409a3eecc0dd1
Author: Harry Ramsey <harry.ramsey@xxxxxxx>
AuthorDate: Wed May 13 13:41:37 2026 +0100
Commit: Michal Orzel <michal.orzel@xxxxxxx>
CommitDate: Fri May 15 09:08:19 2026 +0200
arm/mpu: Introduce `v8r_el1_msa` device tree property for domains
Add a new device tree property `v8r_el1_msa` to select the MSA (memory
system architecture) at EL1 for Armv8-R architecture: MPU or MMU, the
former is the default if the property is not passed.
Implement the dom0less path to parse the new device tree property, add
a new domctl hypercall input parameter `v8r_el1_msa` for arm and
add the sanitisation in arch_sanitise_domain_config(), the parameter
is intended to be used on CONFIG_MPU systems and returns an error if
selected for MMU.
While there, add explicit padding and check that it's zero during
arch domain config sanitisation, given the breaking change, bump the
XEN_DOMCTL_INTERFACE_VERSION.
Signed-off-by: Harry Ramsey <harry.ramsey@xxxxxxx>
Signed-off-by: Luca Fancellu <luca.fancellu@xxxxxxx>
Reviewed-by: Michal Orzel <michal.orzel@xxxxxxx>
---
docs/misc/arm/device-tree/booting.txt | 14 ++++++++
xen/arch/arm/dom0less-build.c | 62 +++++++++++++++++++++++++++++++++
xen/arch/arm/domain.c | 37 ++++++++++++++++++++
xen/arch/arm/include/asm/domain.h | 4 +++
xen/arch/arm/include/asm/domain_build.h | 10 ++++++
xen/arch/arm/mpu/arm64/mm.c | 5 +++
xen/include/public/arch-arm.h | 7 ++++
xen/include/public/domctl.h | 4 +--
8 files changed, 141 insertions(+), 2 deletions(-)
diff --git a/docs/misc/arm/device-tree/booting.txt
b/docs/misc/arm/device-tree/booting.txt
index 977b428608..f73839df09 100644
--- a/docs/misc/arm/device-tree/booting.txt
+++ b/docs/misc/arm/device-tree/booting.txt
@@ -322,6 +322,20 @@ with the following properties:
Should be used together with scmi-smc-passthrough Xen command line
option.
+- v8r_el1_msa
+
+ A string property specifying whether, on Armv8-R systems at EL1, a domain
+ should use PMSAv8 (MPU) or VMSAv8 (MMU).
+
+ - "mmu"
+ Enables VMSAv8 at EL1. This requires hardware support and is only
+ optionally available on AArch64. Not supported on AArch32.
+
+ - "mpu"
+ Enables PMSAv8 at EL1. This is the default behavior when the property is
+ not passed. This configuration requires static allocation (xen,static-mem)
+ and direct mapping (direct-map).
+
Under the "xen,domain" compatible node, one or more sub-nodes are present
for the DomU kernel and ramdisk.
diff --git a/xen/arch/arm/dom0less-build.c b/xen/arch/arm/dom0less-build.c
index 52cf788a45..3f48f74226 100644
--- a/xen/arch/arm/dom0less-build.c
+++ b/xen/arch/arm/dom0less-build.c
@@ -302,6 +302,65 @@ static int __init domu_dt_sci_parse(struct dt_device_node
*node,
return 0;
}
+static int __init
+domu_dt_v8r_el1_msa_parse(const struct dt_device_node *node,
+ struct xen_domctl_createdomain *d_cfg,
+ unsigned int flags)
+{
+ const char *value;
+ int ret;
+
+ if ( !IS_ENABLED(CONFIG_MPU) )
+ {
+ d_cfg->arch.v8r_el1_msa = XEN_DOMCTL_CONFIG_ARM_V8R_EL1_MSA_NONE;
+
+ if ( !dt_property_read_bool(node, "v8r_el1_msa") )
+ return 0;
+
+ printk(XENLOG_ERR
+ "v8r_el1_msa not supported on this build for domain %s\n",
+ dt_node_full_name(node));
+ return -EINVAL;
+ }
+
+ ret = dt_property_read_string(node, "v8r_el1_msa", &value);
+ /* Property absent: PMSA is the default */
+ if ( ret == -EINVAL )
+ value = "mpu";
+ else if ( ret )
+ return ret;
+
+ if ( !strcmp(value, "mpu") )
+ {
+ if ( !(flags & CDF_staticmem) || !(flags & CDF_directmap) )
+ {
+ printk(XENLOG_ERR
+ "v8r_el1_msa=mpu requires static-mem and direct-map for
domain %s\n",
+ dt_node_full_name(node));
+ return -EINVAL;
+ }
+ d_cfg->arch.v8r_el1_msa = XEN_DOMCTL_CONFIG_ARM_V8R_EL1_MSA_PMSA;
+ return 0;
+ }
+
+ if ( !strcmp(value, "mmu") )
+ {
+ if ( !has_v8r_vmsa_support() )
+ {
+ printk(XENLOG_ERR
+ "v8r_el1_msa=mmu unsupported by platform for domain %s\n",
+ dt_node_full_name(node));
+ return -EINVAL;
+ }
+ d_cfg->arch.v8r_el1_msa = XEN_DOMCTL_CONFIG_ARM_V8R_EL1_MSA_VMSA;
+ return 0;
+ }
+
+ printk(XENLOG_ERR "v8r_el1_msa value '%s' not valid for domain %s\n",
+ value, dt_node_full_name(node));
+ return -EINVAL;
+}
+
int __init arch_parse_dom0less_node(struct dt_device_node *node,
struct boot_domain *bd)
{
@@ -315,6 +374,9 @@ int __init arch_parse_dom0less_node(struct dt_device_node
*node,
if ( domu_dt_sci_parse(node, d_cfg) )
panic("Error getting SCI configuration\n");
+ if ( domu_dt_v8r_el1_msa_parse(node, d_cfg, flags) )
+ panic("Error getting v8r_el1_msa configuration\n");
+
if ( !dt_property_read_u32(node, "nr_spis", &d_cfg->arch.nr_spis) )
{
int vpl011_virq = GUEST_VPL011_SPI;
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 26380a807c..baa3a5d708 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -538,6 +538,25 @@ void vcpu_switch_to_aarch64_mode(struct vcpu *v)
v->arch.hcr_el2 |= HCR_RW;
}
+static bool v8r_el1_msa_domain_sanitise_config(
+ const struct xen_domctl_createdomain *config)
+{
+ switch ( config->arch.v8r_el1_msa )
+ {
+ case XEN_DOMCTL_CONFIG_ARM_V8R_EL1_MSA_NONE:
+ return !IS_ENABLED(CONFIG_MPU);
+
+ case XEN_DOMCTL_CONFIG_ARM_V8R_EL1_MSA_PMSA:
+ return IS_ENABLED(CONFIG_MPU);
+
+ case XEN_DOMCTL_CONFIG_ARM_V8R_EL1_MSA_VMSA:
+ return IS_ENABLED(CONFIG_MPU) && IS_ENABLED(CONFIG_ARM_64);
+
+ default:
+ return false;
+ }
+}
+
int arch_sanitise_domain_config(struct xen_domctl_createdomain *config)
{
unsigned int max_vcpus;
@@ -554,6 +573,14 @@ int arch_sanitise_domain_config(struct
xen_domctl_createdomain *config)
return -EINVAL;
}
+ /* Check config structure padding */
+ if ( config->arch.pad )
+ {
+ dprintk(XENLOG_INFO,
+ "Invalid domain configuration during domain creation\n");
+ return -EINVAL;
+ }
+
/* Check feature flags */
if ( sve_vl_bits > 0 )
{
@@ -630,6 +657,12 @@ int arch_sanitise_domain_config(struct
xen_domctl_createdomain *config)
return -EINVAL;
}
+ if ( !v8r_el1_msa_domain_sanitise_config(config) )
+ {
+ dprintk(XENLOG_INFO, "Unsupported v8r_el1_msa value\n");
+ return -EINVAL;
+ }
+
return sci_domain_sanitise_config(config);
}
@@ -722,6 +755,10 @@ int arch_domain_create(struct domain *d,
d->arch.sve_vl = config->arch.sve_vl;
#endif
+#ifdef CONFIG_MPU
+ d->arch.v8r_el1_msa = config->arch.v8r_el1_msa;
+#endif
+
if ( (rc = sci_domain_init(d, config)) != 0 )
goto fail;
diff --git a/xen/arch/arm/include/asm/domain.h
b/xen/arch/arm/include/asm/domain.h
index 46a5cdc0c8..c3d2c4981f 100644
--- a/xen/arch/arm/include/asm/domain.h
+++ b/xen/arch/arm/include/asm/domain.h
@@ -98,6 +98,10 @@ struct arch_domain
#endif
struct resume_info resume_ctx;
+
+#ifdef CONFIG_MPU
+ uint8_t v8r_el1_msa;
+#endif
} __cacheline_aligned;
struct arch_vcpu
diff --git a/xen/arch/arm/include/asm/domain_build.h
b/xen/arch/arm/include/asm/domain_build.h
index 6674dac5e2..df8b361b3d 100644
--- a/xen/arch/arm/include/asm/domain_build.h
+++ b/xen/arch/arm/include/asm/domain_build.h
@@ -19,6 +19,16 @@ int prepare_acpi(struct domain *d, struct kernel_info
*kinfo);
int add_ext_regions(unsigned long s_gfn, unsigned long e_gfn, void *data);
+#if defined(CONFIG_MPU) && defined(CONFIG_ARM_64)
+/* Utility function to determine if an Armv8-R processor supports VMSA. */
+bool has_v8r_vmsa_support(void);
+#else
+static inline bool has_v8r_vmsa_support(void)
+{
+ return false;
+}
+#endif /* CONFIG_MPU */
+
#endif
/*
diff --git a/xen/arch/arm/mpu/arm64/mm.c b/xen/arch/arm/mpu/arm64/mm.c
index ed643cad40..b07e729a7d 100644
--- a/xen/arch/arm/mpu/arm64/mm.c
+++ b/xen/arch/arm/mpu/arm64/mm.c
@@ -32,6 +32,11 @@
break; \
}
+bool has_v8r_vmsa_support(void)
+{
+ return system_cpuinfo.mm64.msa_frac == MM64_MSA_FRAC_VMSA_SUPPORT;
+}
+
/*
* Armv8-R supports direct access and indirect access to the MPU regions
through
* registers:
diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
index cd563cf706..7d6f87e8b2 100644
--- a/xen/include/public/arch-arm.h
+++ b/xen/include/public/arch-arm.h
@@ -330,6 +330,10 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
#define XEN_DOMCTL_CONFIG_ARM_SCI_NONE 0
#define XEN_DOMCTL_CONFIG_ARM_SCI_SCMI_SMC 1
+#define XEN_DOMCTL_CONFIG_ARM_V8R_EL1_MSA_NONE 0
+#define XEN_DOMCTL_CONFIG_ARM_V8R_EL1_MSA_PMSA 1
+#define XEN_DOMCTL_CONFIG_ARM_V8R_EL1_MSA_VMSA 2
+
struct xen_arch_domainconfig {
/* IN/OUT */
uint8_t gic_version;
@@ -355,6 +359,9 @@ struct xen_arch_domainconfig {
uint32_t clock_frequency;
/* IN */
uint8_t arm_sci_type;
+ /* IN */
+ uint8_t v8r_el1_msa;
+ uint16_t pad;
};
#endif /* __XEN__ || __XEN_TOOLS__ */
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 8f6708c0a7..23124547f3 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -30,9 +30,9 @@
* fields) don't require a change of the version.
* Stable ops are NOT covered by XEN_DOMCTL_INTERFACE_VERSION!
*
- * Last version bump: Xen 4.19
+ * Last version bump: Xen 4.22
*/
-#define XEN_DOMCTL_INTERFACE_VERSION 0x00000017
+#define XEN_DOMCTL_INTERFACE_VERSION 0x00000018
/*
* NB. xen_domctl.domain is an IN/OUT parameter for this operation.
--
generated by git-patchbot for /home/xen/git/xen.git#master
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |