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@arm.com>
Signed-off-by: Luca Fancellu <luca.fancellu@arm.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
This commit is contained in:
Harry Ramsey authored and Michal Orzel committed 2026-05-15 09:08:19 +02:00
1 parent a5aa6a7379
commit 1afacf7b15
8 files changed
+141 -2

No files matched your search

+14
View File
@@ -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.
+62
View File
@@ -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;
+37
View File
@@ -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;
+4
View File
@@ -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
+10
View File
@@ -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
/*
+5
View File
@@ -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:
+7
View File
@@ -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__ */
+2 -2
View File
@@ -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.
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.