dom0less: Parse dom0less bindings into createdomain input args

The builder in common code already does this, but it's not callable
independently from a separate location. Create a function x86 can
call to use its own domain builder, using createdomain arguments
as the parsed data.

The bindings are moved on the next patch so it's strict code motion.

Signed-off-by: Alejandro Vallejo <alejandro.garciavallejo@amd.com>
Reviewed-by: Stefano Stabellini <stefano.stabellini@amd.com>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
This commit is contained in:
Alejandro Vallejo authored and Stefano Stabellini committed 2025-07-23 13:38:07 -07:00
1 parent cddc790705
commit 2fd83ec8a7
4 files changed
+154 -126

No files matched your search

+2 -1
View File
@@ -3,7 +3,8 @@ obj-$(CONFIG_HAS_DEVICE_TREE_DISCOVERY) += bootinfo-fdt.init.o
obj-$(CONFIG_HAS_DEVICE_TREE_DISCOVERY) += bootinfo.init.o
obj-y += device-tree.o
obj-$(CONFIG_DOMAIN_BUILD_HELPERS) += domain-build.init.o
obj-$(CONFIG_DOM0LESS_BOOT) += dom0less-build.init.o
obj-$(filter $(CONFIG_DOM0LESS_BOOT),$(CONFIG_HAS_DEVICE_TREE_DISCOVERY)) += dom0less-build.init.o
obj-$(CONFIG_DOM0LESS_BOOT) += dom0less-bindings.init.o
obj-$(CONFIG_OVERLAY_DTB) += dt-overlay.o
obj-$(CONFIG_HAS_DEVICE_TREE_DISCOVERY) += intc.o
obj-$(CONFIG_DOMAIN_BUILD_HELPERS) += kernel.o
+145
View File
@@ -0,0 +1,145 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <xen/bootfdt.h>
#include <xen/device_tree.h>
#include <xen/dom0less-build.h>
#include <xen/domain.h>
#include <xen/grant_table.h>
#include <xen/llc-coloring.h>
#include <xen/sched.h>
#include <public/bootfdt.h>
#include <public/domctl.h>
int __init parse_dom0less_node(struct dt_device_node *node,
struct boot_domain *bd)
{
struct xen_domctl_createdomain *d_cfg = &bd->create_cfg;
unsigned int *flags = &bd->create_flags;
struct dt_device_node *cpupool_node;
uint32_t val;
bool has_dtb = false;
bool iommu = false;
const char *dom0less_iommu = NULL;
if ( !dt_device_is_compatible(node, "xen,domain") )
return -ENOENT;
*flags = 0;
*d_cfg = (struct xen_domctl_createdomain){
.max_evtchn_port = 1023,
.max_grant_frames = -1,
.max_maptrack_frames = -1,
.grant_opts = XEN_DOMCTL_GRANT_version(opt_gnttab_max_version),
};
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);
#ifdef CONFIG_GRANT_TABLE
d_cfg->max_grant_frames = gnttab_dom0_frames();
#endif
d_cfg->max_evtchn_port = -1;
*flags |= CDF_hardware;
iommu = true;
}
if ( val & DOMAIN_CAPS_XENSTORE )
{
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 )
panic("LLC coloring and static memory are incompatible\n");
*flags |= CDF_staticmem;
}
if ( dt_property_read_bool(node, "direct-map") )
{
if ( !(*flags & CDF_staticmem) )
panic("direct-map is not valid for domain %s without static allocation.\n",
dt_node_name(node));
*flags |= CDF_directmap;
}
if ( !dt_property_read_u32(node, "cpus", &d_cfg->max_vcpus) )
panic("Missing property 'cpus' for domain %s\n",
dt_node_name(node));
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;
/* Get the optional property domain-cpupool */
cpupool_node = dt_parse_phandle(node, "domain-cpupool", 0);
if ( cpupool_node )
{
int pool_id = btcpupools_get_domain_pool_id(cpupool_node);
if ( pool_id < 0 )
panic("Error getting cpupool id from domain-cpupool (%d)\n",
pool_id);
d_cfg->cpupool_id = pool_id;
}
if ( dt_property_read_u32(node, "max_grant_version", &val) )
d_cfg->grant_opts = XEN_DOMCTL_GRANT_version(val);
if ( dt_property_read_u32(node, "max_grant_frames", &val) )
{
if ( val > INT32_MAX )
panic("max_grant_frames (%"PRIu32") overflow\n", val);
d_cfg->max_grant_frames = val;
}
if ( dt_property_read_u32(node, "max_maptrack_frames", &val) )
{
if ( val > INT32_MAX )
panic("max_maptrack_frames (%"PRIu32") overflow\n", val);
d_cfg->max_maptrack_frames = val;
}
#ifdef CONFIG_HAS_LLC_COLORING
dt_property_read_string(node, "llc-colors", &bd->llc_colors_str);
if ( !llc_coloring_enabled && bd->llc_colors_str )
panic("'llc-colors' found, but LLC coloring is disabled\n");
#endif
return arch_parse_dom0less_node(node, bd);
}
+4 -125
View File
@@ -831,138 +831,17 @@ void __init create_domUs(void)
BUG_ON(chosen == NULL);
dt_for_each_child_node(chosen, node)
{
const char *dom0less_iommu;
bool iommu = false;
const struct dt_device_node *cpupool_node;
struct kernel_info ki = KERNEL_INFO_INIT;
struct xen_domctl_createdomain *d_cfg = &ki.bd.create_cfg;
unsigned int *flags = &ki.bd.create_flags;
bool has_dtb = false;
uint32_t val;
int rc;
int rc = parse_dom0less_node(node, &ki.bd);
if ( !dt_device_is_compatible(node, "xen,domain") )
if ( rc == -ENOENT )
continue;
if ( rc )
panic("Malformed DTB: Invalid domain %s\n", dt_node_name(node));
if ( (max_init_domid + 1) >= DOMID_FIRST_RESERVED )
panic("No more domain IDs available\n");
d_cfg->max_evtchn_port = 1023;
d_cfg->max_grant_frames = -1;
d_cfg->max_maptrack_frames = -1;
d_cfg->grant_opts = XEN_DOMCTL_GRANT_version(opt_gnttab_max_version);
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);
#ifdef CONFIG_GRANT_TABLE
d_cfg->max_grant_frames = gnttab_dom0_frames();
#endif
d_cfg->max_evtchn_port = -1;
*flags |= CDF_hardware;
iommu = true;
}
if ( val & DOMAIN_CAPS_XENSTORE )
{
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 )
panic("LLC coloring and static memory are incompatible\n");
*flags |= CDF_staticmem;
}
if ( dt_property_read_bool(node, "direct-map") )
{
if ( !(*flags & CDF_staticmem) )
panic("direct-map is not valid for domain %s without static allocation.\n",
dt_node_name(node));
*flags |= CDF_directmap;
}
if ( !dt_property_read_u32(node, "cpus", &d_cfg->max_vcpus) )
panic("Missing property 'cpus' for domain %s\n",
dt_node_name(node));
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;
/* Get the optional property domain-cpupool */
cpupool_node = dt_parse_phandle(node, "domain-cpupool", 0);
if ( cpupool_node )
{
int pool_id = btcpupools_get_domain_pool_id(cpupool_node);
if ( pool_id < 0 )
panic("Error getting cpupool id from domain-cpupool (%d)\n",
pool_id);
d_cfg->cpupool_id = pool_id;
}
if ( dt_property_read_u32(node, "max_grant_version", &val) )
d_cfg->grant_opts = XEN_DOMCTL_GRANT_version(val);
if ( dt_property_read_u32(node, "max_grant_frames", &val) )
{
if ( val > INT32_MAX )
panic("max_grant_frames (%"PRIu32") overflow\n", val);
d_cfg->max_grant_frames = val;
}
if ( dt_property_read_u32(node, "max_maptrack_frames", &val) )
{
if ( val > INT32_MAX )
panic("max_maptrack_frames (%"PRIu32") overflow\n", val);
d_cfg->max_maptrack_frames = val;
}
#ifdef CONFIG_HAS_LLC_COLORING
dt_property_read_string(node, "llc-colors", &ki.bd.llc_colors_str);
if ( !llc_coloring_enabled && ki.bd.llc_colors_str )
panic("'llc-colors' found, but LLC coloring is disabled\n");
#endif
if ( (rc = arch_parse_dom0less_node(node, &ki.bd)) )
panic("error parsing arch-specific dom0less props (rc=%d)", rc);
/*
* The variable max_init_domid is initialized with zero, so here it's
* very important to use the pre-increment operator to call
+3
View File
@@ -45,6 +45,9 @@ void create_domUs(void);
bool is_dom0less_mode(void);
void set_xs_domain(struct domain *d);
int parse_dom0less_node(struct dt_device_node *node,
struct boot_domain *bd);
int arch_parse_dom0less_node(struct dt_device_node *node,
struct boot_domain *bd);
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.