mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
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:
1 parent
a5aa6a7379
commit
1afacf7b15
8 files changed
+141
-2
No files matched your search
@@ -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.
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
/*
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||