xen/arm: Add capabilities to dom0less

Add a capabilities property to dom0less to allow building a
disaggregated system.  Only a single hardware domain and single xenstore
domain can be specified.  Multiple control domains are possible.

Introduce bootfdt.h to contain these constants.

When using the hardware or xenstore capabilities, adjust the grant and
event channel limits similar to dom0.

For a hardware domain, disallow specifying "vpl011", "nr_spis",
"multiboot,device-tree" and "passthrough" nodes.  Also, require an IOMMU
when not direct-mapped,

Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
This commit is contained in:
Jason Andryuk authored and Stefano Stabellini committed 2025-04-18 13:41:29 -07:00
1 parent 00eee5a0e0
commit df68a4cb7e
4 files changed
+98 -4

No files matched your search

+11
View File
@@ -167,6 +167,17 @@ with the following properties:
Refer to docs/misc/cache_coloring.rst for syntax. This option is applicable
only to Arm64 guests.
- capabilities
Optional. A 32-bit integer representing a bit field of domain capabilities
for a disaggregated system. A traditional dom0 has all of these
capabilities, and a domU has none of them.
0x1 DOMAIN_CAPS_CONTROL - A privileged, control domain
0x2 DOMAIN_CAPS_HARDWARE - The hardware domain - there can be only 1
0x4 DOMAIN_CAPS_XENSTORE - The xenstore domain - there can be only 1
The default is no capabilities.
- vpl011
An empty property to enable/disable a virtual pl011 for the guest to
+54 -3
View File
@@ -12,11 +12,13 @@
#include <xen/sizes.h>
#include <xen/vmap.h>
#include <public/bootfdt.h>
#include <public/io/xs_wire.h>
#include <asm/arm64/sve.h>
#include <asm/dom0less-build.h>
#include <asm/domain_build.h>
#include <asm/grant_table.h>
#include <asm/static-memory.h>
#include <asm/static-shmem.h>
@@ -928,6 +930,8 @@ static int __init construct_domU(struct domain *d,
d->max_vcpus, mem);
kinfo.vpl011 = dt_property_read_bool(node, "vpl011");
if ( kinfo.vpl011 && is_hardware_domain(d) )
panic("hardware domain cannot specify vpl011\n");
rc = dt_property_read_string(node, "xen,enhanced", &dom0less_enhanced);
if ( rc == -EILSEQ ||
@@ -1043,6 +1047,37 @@ void __init create_domUs(void)
if ( (max_init_domid + 1) >= DOMID_FIRST_RESERVED )
panic("No more domain IDs available\n");
if ( dt_property_read_u32(node, "capabilities", &val) )
{
if ( val & ~DOMAIN_CAPS_MASK )
panic("Invalid capabilities (%"PRIx32")\n", val);
if ( val & DOMAIN_CAPS_CONTROL )
flags |= CDF_privileged;
if ( val & DOMAIN_CAPS_HARDWARE )
{
if ( hardware_domain )
panic("Only 1 hardware domain can be specified! (%pd)\n",
hardware_domain);
d_cfg.max_grant_frames = gnttab_dom0_frames();
d_cfg.max_evtchn_port = -1;
flags |= CDF_hardware;
iommu = true;
}
if ( val & DOMAIN_CAPS_XENSTORE )
{
if ( xs_domid != DOMID_INVALID )
panic("Only 1 xenstore domain can be specified! (%u)\n",
xs_domid);
d_cfg.flags |= XEN_DOMCTL_CDF_xs_domain;
d_cfg.max_evtchn_port = -1;
}
}
if ( dt_find_property(node, "xen,static-mem", NULL) )
{
if ( llc_coloring_enabled )
@@ -1064,12 +1099,26 @@ void __init create_domUs(void)
panic("Missing property 'cpus' for domain %s\n",
dt_node_name(node));
if ( !dt_property_read_string(node, "passthrough", &dom0less_iommu) &&
!strcmp(dom0less_iommu, "enabled") )
iommu = true;
if ( !dt_property_read_string(node, "passthrough", &dom0less_iommu) )
{
if ( flags & CDF_hardware )
panic("Don't specify passthrough for hardware domain\n");
if ( !strcmp(dom0less_iommu, "enabled") )
iommu = true;
}
if ( (flags & CDF_hardware) && !(flags & CDF_directmap) &&
!iommu_enabled )
panic("non-direct mapped hardware domain requires iommu\n");
if ( dt_find_compatible_node(node, NULL, "multiboot,device-tree") )
{
if ( flags & CDF_hardware )
panic("\"multiboot,device-tree\" incompatible with hardware domain\n");
has_dtb = true;
}
if ( iommu_enabled && (iommu || has_dtb) )
d_cfg.flags |= XEN_DOMCTL_CDF_iommu;
@@ -1106,6 +1155,8 @@ void __init create_domUs(void)
d_cfg.arch.nr_spis = MAX(d_cfg.arch.nr_spis,
vpl011_virq - 32 + 1);
}
else if ( flags & CDF_hardware )
panic("nr_spis cannot be specified for hardware domain\n");
/* Get the optional property domain-cpupool */
cpupool_node = dt_parse_phandle(node, "domain-cpupool", 0);
+2 -1
View File
@@ -608,7 +608,8 @@ int arch_sanitise_domain_config(struct xen_domctl_createdomain *config)
{
unsigned int max_vcpus;
unsigned int flags_required = (XEN_DOMCTL_CDF_hvm | XEN_DOMCTL_CDF_hap);
unsigned int flags_optional = (XEN_DOMCTL_CDF_iommu | XEN_DOMCTL_CDF_vpmu);
unsigned int flags_optional = (XEN_DOMCTL_CDF_iommu | XEN_DOMCTL_CDF_vpmu |
XEN_DOMCTL_CDF_xs_domain );
unsigned int sve_vl_bits = sve_decode_vl(config->arch.sve_vl);
if ( (config->flags & ~flags_optional) != flags_required )
+31
View File
@@ -0,0 +1,31 @@
/* SPDX-License-Identifier: MIT */
/*
* Xen Device Tree boot information
*
* Information for configuring Xen domains created at boot time.
*/
#ifndef __XEN_PUBLIC_BOOTFDT_H__
#define __XEN_PUBLIC_BOOTFDT_H__
/*
* Domain Capabilities specified in the "capabilities" property. Use of
* this property allows splitting up the monolithic dom0 into separate,
* less privileged components. A regular domU has no capabilities
* (which is the default if nothing is specified). A traditional dom0
* has all three capabilities.
*/
/* Control/Privileged domain capable of affecting other domains. */
#define DOMAIN_CAPS_CONTROL (1U << 0)
/*
* Hardware domain controlling physical hardware. Typically providing
* backends to other domains.
*/
#define DOMAIN_CAPS_HARDWARE (1U << 1)
/* Xenstore domain. */
#define DOMAIN_CAPS_XENSTORE (1U << 2)
#define DOMAIN_CAPS_MASK (DOMAIN_CAPS_CONTROL | DOMAIN_CAPS_HARDWARE | \
DOMAIN_CAPS_XENSTORE)
#endif /* __XEN_PUBLIC_BOOTFDT_H__ */
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.