From: Grygorii Strashko <grygorii_strashko@epam.com>
As was indicated in [1][2], performing guest kernel probe after creating
domain is not robust.
Hence, rework Arm dom0 creation sequence to probe guest kernel first,
before creating domain, so guest type (32/64bit) can be properly identified
and dom0 type configured correctly from very beginning.
To move kernel_probe() before dom0 domain_create() the domain references
need to be removed from kernel_probe():
- remove ASSERT(is_hardware_domain(info->bd.d))
- remove printing domain id ("%pd") from "Loading kernel from boot module.."
log msg.
[1] https://lists.xen.org/archives/html/xen-devel/2025-07/msg01647.html
[2] https://lists.xen.org/archives/html/xen-devel/2025-07/msg01648.html
Signed-off-by: Grygorii Strashko <grygorii_strashko@epam.com>
---
xen/arch/arm/domain_build.c | 32 +++++++++++++++++++-------------
xen/common/device-tree/kernel.c | 6 ++----
2 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index fc9bcc6fbbd5..59966f1bcd49 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -1954,16 +1954,13 @@ int __init construct_domain(struct domain *d, struct kernel_info *kinfo)
return 0;
}
-static int __init construct_dom0(struct domain *d)
+static int __init construct_dom0(struct kernel_info *kinfo)
{
- struct kernel_info kinfo = KERNEL_INFO_INIT;
- int rc;
+ struct domain *d = kinfo->bd.d;
/* Sanity! */
BUG_ON(d->domain_id != 0);
- printk("*** LOADING DOMAIN 0 ***\n");
-
/* The ordering of operands is to work around a clang5 issue. */
if ( CONFIG_DOM0_MEM[0] && !dom0_mem_set )
parse_dom0_mem(CONFIG_DOM0_MEM);
@@ -1976,14 +1973,9 @@ static int __init construct_dom0(struct domain *d)
d->max_pages = dom0_mem >> PAGE_SHIFT;
- kinfo.unassigned_mem = dom0_mem;
- kinfo.bd.d = d;
+ kinfo->unassigned_mem = dom0_mem;
- rc = kernel_probe(&kinfo, NULL);
- if ( rc < 0 )
- return rc;
-
- return construct_hwdom(&kinfo, NULL);
+ return construct_hwdom(kinfo, NULL);
}
int __init construct_hwdom(struct kernel_info *kinfo,
@@ -2040,6 +2032,7 @@ int __init construct_hwdom(struct kernel_info *kinfo,
void __init create_dom0(void)
{
+ struct kernel_info kinfo = KERNEL_INFO_INIT;
struct domain *dom0;
struct xen_domctl_createdomain dom0_cfg = {
.flags = XEN_DOMCTL_CDF_hvm | XEN_DOMCTL_CDF_hap |
@@ -2052,6 +2045,17 @@ void __init create_dom0(void)
unsigned int flags = CDF_privileged | CDF_hardware;
int rc;
+ printk("*** LOADING DOMAIN 0 ***\n");
+
+ rc = kernel_probe(&kinfo, NULL);
+ if ( rc < 0 )
+ panic("Error probing domain 0 guest kernel (rc = %d)\n", rc);
+
+#ifdef CONFIG_ARM_64
+ if ( kinfo.is_32bit_type )
+ dom0_cfg.flags |= XEN_DOMCTL_CDF_is_32bits;
+#endif
+
/* The vGIC for DOM0 is exactly emulating the hardware GIC */
dom0_cfg.arch.gic_version = XEN_DOMCTL_CONFIG_GIC_NATIVE;
dom0_cfg.arch.nr_spis = VGIC_DEF_NR_SPIS;
@@ -2078,13 +2082,15 @@ void __init create_dom0(void)
if ( IS_ERR(dom0) )
panic("Error creating domain 0 (rc = %ld)\n", PTR_ERR(dom0));
+ kinfo.bd.d = dom0;
+
if ( llc_coloring_enabled && (rc = dom0_set_llc_colors(dom0)) )
panic("Error initializing LLC coloring for domain 0 (rc = %d)\n", rc);
if ( vcpu_create(dom0, 0) == NULL )
panic("Error creating domain 0 vcpu0\n");
- rc = construct_dom0(dom0);
+ rc = construct_dom0(&kinfo);
if ( rc )
panic("Could not set up DOM0 guest OS (rc = %d)\n", rc);
diff --git a/xen/common/device-tree/kernel.c b/xen/common/device-tree/kernel.c
index 28096121a52d..f67229f66d30 100644
--- a/xen/common/device-tree/kernel.c
+++ b/xen/common/device-tree/kernel.c
@@ -140,8 +140,6 @@ int __init kernel_probe(struct kernel_info *info,
/* domain is NULL only for the hardware domain */
if ( domain == NULL )
{
- ASSERT(is_hardware_domain(info->bd.d));
-
mod = boot_module_find_by_kind(BOOTMOD_KERNEL);
info->bd.kernel = mod;
@@ -204,8 +202,8 @@ int __init kernel_probe(struct kernel_info *info,
return -ENOENT;
}
- printk("Loading %pd kernel from boot module @ %"PRIpaddr"\n",
- info->bd.d, info->bd.kernel->start);
+ printk("Loading kernel from boot module @ %"PRIpaddr"\n",
+ info->bd.kernel->start);
if ( info->bd.initrd )
printk("Loading ramdisk from boot module @ %"PRIpaddr"\n",
info->bd.initrd->start);
--
2.34.1