@@ -8,6 +8,7 @@
#include <xen/libfdt/libfdt.h>
#include <asm/bootinfo.h>
+#include <asm/guest.h>
#include <asm/page.h>
#include <asm/setup.h>
@@ -61,10 +62,40 @@ static int __init dom0less_module_index(
static int __init process_domain_node(
struct boot_info *bi, void *fdt, int dom_node)
{
- int node;
+ int node, property;
struct boot_domain *bd = &bi->domains[bi->nr_domains];
const char *name = fdt_get_name(fdt, dom_node, NULL) ?: "unknown";
+ fdt_for_each_property_offset(property, fdt, dom_node)
+ {
+ const struct fdt_property *prop;
+ const char *prop_name;
+ int name_len;
+
+ prop = fdt_get_property_by_offset(fdt, property, NULL);
+ if ( !prop )
+ continue; /* silently skip */
+
+ prop_name = fdt_get_string(fdt, fdt32_to_cpu(prop->nameoff), &name_len);
+
+ if ( strncmp(prop_name, "domid", name_len) == 0 )
+ {
+ uint32_t val = DOMID_INVALID;
+ if ( fdt_prop_as_u32(prop, &val) != 0 )
+ {
+ printk(" failed processing domain id for domain %s\n", name);
+ return -EINVAL;
+ }
+ if ( val >= DOMID_FIRST_RESERVED )
+ {
+ printk(" invalid domain id for domain %s\n", name);
+ return -EINVAL;
+ }
+ bd->domid = (domid_t)val;
+ printk(" domid: %d\n", bd->domid);
+ }
+ }
+
fdt_for_each_subnode(node, fdt, dom_node)
{
if ( fdt_node_check_compatible(fdt, node, "multiboot,kernel") == 0 )
@@ -125,7 +156,29 @@ static int __init process_domain_node(
else if (
fdt_node_check_compatible(fdt, node, "multiboot,ramdisk") == 0 )
{
- int idx = dom0less_module_node(fdt, node, size_size, address_size);
+ unsigned int idx;
+ int ret = 0;
+
+ if ( bd->ramdisk )
+ {
+ printk(XENLOG_ERR "Duplicate ramdisk module for domain %s)\n",
+ name);
+ continue;
+ }
+
+ /* Try hyperlaunch property, fall back to dom0less property. */
+ if ( hl_module_index(fdt, node, &idx) < 0 )
+ {
+ int address_size = fdt_address_cells(fdt, dom_node);
+ int size_size = fdt_size_cells(fdt, dom_node);
+
+ if ( address_size < 0 || size_size < 0 )
+ ret = -EINVAL;
+ else
+ ret = dom0less_module_index(
+ fdt, node, size_size, address_size, &idx);
+ }
+
if ( idx < 0 )
{
printk(" failed processing ramdisk module for domain %s\n",
@@ -154,6 +207,12 @@ static int __init process_domain_node(
return -EFAULT;
}
+ if ( bd->domid == DOMID_INVALID )
+ bd->domid = get_initial_domain_id();
+ else if ( bd->domid != get_initial_domain_id() )
+ printk(XENLOG_WARNING
+ "WARN: Booting without initial domid not supported.\n");
+
return 0;
}
@@ -1029,8 +1029,9 @@ static struct domain *__init create_dom0(struct boot_info *bi)
if ( iommu_enabled )
dom0_cfg.flags |= XEN_DOMCTL_CDF_iommu;
- /* Create initial domain. Not d0 for pvshim. */
- bd->domid = get_initial_domain_id();
+ if ( bd->domid == DOMID_INVALID )
+ /* Create initial domain. Not d0 for pvshim. */
+ bd->domid = get_initial_domain_id();
d = domain_create(bd->domid, &dom0_cfg, pv_shim ? 0 : CDF_privileged);
if ( IS_ERR(d) )
panic("Error creating d%u: %ld\n", bd->domid, PTR_ERR(d));
@@ -28,6 +28,15 @@ static inline int __init fdt_cell_as_u64(const fdt32_t *cell, uint64_t *val)
return 0;
}
+static inline int __init fdt_prop_as_u32(
+ const struct fdt_property *prop, uint32_t *val)
+{
+ if ( !prop || fdt32_to_cpu(prop->len) < sizeof(u32) )
+ return -EINVAL;
+
+ return fdt_cell_as_u32((fdt32_t *)prop->data, val);
+}
+
static inline int __init fdt_get_prop_by_offset(
const void *fdt, int node, const char *name, unsigned long *offset)
{
Introduce the ability to specify the desired domain id for the domain definition. The domain id will be populated in the domid property of the domain node in the device tree configuration. Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com> --- Changes since v1 - coding style changes - moved comment with code movement - updated warning message - unrolled match_fdt_property() --- xen/arch/x86/domain-builder/fdt.c | 63 ++++++++++++++++++++++++++++- xen/arch/x86/setup.c | 5 ++- xen/include/xen/libfdt/libfdt-xen.h | 9 +++++ 3 files changed, 73 insertions(+), 4 deletions(-)