From: Grygorii Strashko <grygorii_stras...@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_stras...@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

Reply via email to