[PATCH v6] xen/arm, xen/common: Add Kconfig option to control Dom0 boot

Oleksii Moisieiev posted 1 patch 2 days, 16 hours ago
xen/arch/arm/Kconfig                 |  3 ++-
xen/arch/arm/arm64/sve.c             |  2 ++
xen/arch/arm/domain_build.c          | 10 ++++++++++
xen/arch/arm/include/asm/arm64/sve.h |  2 ++
xen/arch/arm/setup.c                 |  7 ++++---
xen/arch/x86/Kconfig                 |  1 +
xen/common/Kconfig                   | 14 ++++++++++++++
xen/common/domain.c                  |  3 +++
xen/common/llc-coloring.c            |  6 ++++++
9 files changed, 44 insertions(+), 4 deletions(-)
[PATCH v6] xen/arm, xen/common: Add Kconfig option to control Dom0 boot
Posted by Oleksii Moisieiev 2 days, 16 hours ago
Introduce HAS_DOM0 and a default-enabled DOM0_BOOT option in common
Kconfig. Arm and x86 select HAS_DOM0. Expert configurations can disable
DOM0_BOOT; this patch implements the corresponding code exclusion on Arm.
Making x86 honor the option remains a TODO, potentially as part of the
Hyperlaunch work. In particular, x86 still builds and boots its legacy
Dom0 even if DOM0_BOOT is disabled.

On Arm, exclude legacy Dom0 creation and its private memory, vCPU, SVE
and LLC coloring options when DOM0_BOOT is disabled. Hide DOM0_MEM in
that configuration and disallow ACPI, since the alternative dom0less boot
path requires device tree. Keep the x86 DOM0_MEM setting and dom0 command
line parser available until x86 honors DOM0_BOOT.

Retain the domain and hardware-domain builders, guest SVE and LLC
coloring support, and Xenstore domain setup: these are also used by
dom0less guests. This is a switch for legacy Dom0 boot support, not for
all control-domain or hardware-domain functionality, and it does not
claim to remove every unreachable path or establish MISRA compliance.

Check for dom0less mode once in the Arm boot path. Otherwise, create Dom0
when supported or panic when neither boot mode is available.

RISC-V does not yet have a legacy Dom0 boot path in this staging tree,
so it does not select HAS_DOM0.

Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev@epam.com>
Acked-by: Jan Beulich <jbeulich@suse.com>

---

Changes in v6:
- Use the single dom0less check and else-if chain suggested by Michal.
- Exclude Dom0-only memory, SVE and LLC coloring options and code.
- Make Arm ACPI depend on DOM0_BOOT.
- Expose the common option on x86 and document the implementation TODO.
- Explain why RISC-V does not yet select HAS_DOM0.
- Replace the broad dead-code/MISRA claims with the actual scope.

Changes in v5:
- rebased on top of the latest staging.
- add Ack

Changes in v4:
- change Misra rule to 2.1 from 2.2 in description
- remove extra dependencies for ARM architecture from DOM0_BOOT
- rephrase DOM0_BOOT help by adding hyperlaunch
- DOM0_BOOT is mandatory for x86 architecture

Changes in v3:
- rephrase error message when dom0less mode wasn't detected while dom0
is disabled.
- rephrase help message for DOM0_BOOT config option
- update DOM0_BOOT dependencies for X86

Changes in v2:
- decided not to rename HAS_DOM0 (HAS_OPTIONAL_DOM0 was another option
suggested in ML) because in this case HAS_DOM0LESS should be renamed
either.
- fix order of HAS_DOM0 config parameter
- add HAS_DOM0 option to x86 architecture.

CONFIG_DOM0_BOOT Kconfig option was introduced to make the Dom0
regular (legacy) domain an optional feature that can be compiled out
from the Xen hypervisor build.

The primary motivation for this change is to enhance modularity and
produce a cleaner, more specialized hypervisor binary when a control
domain is not needed. In many embedded or dedicated systems, Xen is
used in a "dom0less" configuration where guests are pre-configured and
launched directly by the hypervisor. In these scenarios, the entire
subsystem for booting and managing Dom0 is unnecessary.

---
 xen/arch/arm/Kconfig                 |  3 ++-
 xen/arch/arm/arm64/sve.c             |  2 ++
 xen/arch/arm/domain_build.c          | 10 ++++++++++
 xen/arch/arm/include/asm/arm64/sve.h |  2 ++
 xen/arch/arm/setup.c                 |  7 ++++---
 xen/arch/x86/Kconfig                 |  1 +
 xen/common/Kconfig                   | 14 ++++++++++++++
 xen/common/domain.c                  |  3 +++
 xen/common/llc-coloring.c            |  6 ++++++
 9 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
index b9c5c40678..4d696ff33f 100644
--- a/xen/arch/arm/Kconfig
+++ b/xen/arch/arm/Kconfig
@@ -18,6 +18,7 @@ config ARM
 	select GENERIC_UART_INIT
 	select HAS_ALTERNATIVE if HAS_VMAP
 	select HAS_DEVICE_TREE_DISCOVERY
+	select HAS_DOM0
 	select HAS_DOM0LESS
 	select HAS_GRANT_CACHE_FLUSH if GRANT_TABLE
 	select HAS_SHARED_INFO
@@ -105,7 +106,7 @@ source "arch/Kconfig"
 
 config ACPI
 	bool "ACPI (Advanced Configuration and Power Interface) Support (UNSUPPORTED)" if UNSUPPORTED
-	depends on ARM_64 && ARM_EFI
+	depends on ARM_64 && ARM_EFI && DOM0_BOOT
 	help
 
 	  Advanced Configuration and Power Interface (ACPI) support for Xen is
diff --git a/xen/arch/arm/arm64/sve.c b/xen/arch/arm/arm64/sve.c
index 23a9d0ba66..08ca49bd7f 100644
--- a/xen/arch/arm/arm64/sve.c
+++ b/xen/arch/arm/arm64/sve.c
@@ -13,8 +13,10 @@
 #include <asm/processor.h>
 #include <asm/system.h>
 
+#ifdef CONFIG_DOM0_BOOT
 /* opt_dom0_sve: allow Dom0 to use SVE and set maximum vector length. */
 int __initdata opt_dom0_sve;
+#endif
 
 extern unsigned int sve_get_hw_vl(void);
 
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 72f6f7539a..f047d49f24 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -44,8 +44,10 @@
 #include <asm/grant_table.h>
 #include <xen/serial.h>
 
+#ifdef CONFIG_DOM0_BOOT
 static unsigned int __initdata opt_dom0_max_vcpus;
 integer_param("dom0_max_vcpus", opt_dom0_max_vcpus);
+#endif
 
 /*
  * If true, the extended regions support is enabled for dom0 and
@@ -54,6 +56,7 @@ integer_param("dom0_max_vcpus", opt_dom0_max_vcpus);
 static bool __initdata opt_ext_regions = true;
 boolean_param("ext_regions", opt_ext_regions);
 
+#ifdef CONFIG_DOM0_BOOT
 static u64 __initdata dom0_mem;
 static bool __initdata dom0_mem_set;
 
@@ -87,6 +90,7 @@ int __init parse_arch_dom0_param(const char *s, const char *e)
 
     return -EINVAL;
 }
+#endif /* CONFIG_DOM0_BOOT */
 
 /* Override macros from asm/page.h to make them work with mfn_t */
 #undef virt_to_mfn
@@ -124,6 +128,7 @@ paddr_t __init hwdom_get_fdt_alloc_size(void)
     return ACPI_DOM0_FDT_MIN_SIZE;
 }
 
+#ifdef CONFIG_DOM0_BOOT
 unsigned int __init dom0_max_vcpus(void)
 {
     if ( opt_dom0_max_vcpus == 0 )
@@ -136,6 +141,7 @@ unsigned int __init dom0_max_vcpus(void)
 
     return opt_dom0_max_vcpus;
 }
+#endif
 
 /*
  * Insert the given pages into a memory bank, banks are ordered by address.
@@ -1865,6 +1871,7 @@ int __init construct_domain(struct domain *d, struct kernel_info *kinfo)
     return 0;
 }
 
+#ifdef CONFIG_DOM0_BOOT
 static int __init construct_dom0(struct domain *d)
 {
     struct kernel_info kinfo = KERNEL_INFO_INIT;
@@ -1903,6 +1910,7 @@ static int __init construct_dom0(struct domain *d)
 
     return construct_hwdom(&kinfo, NULL);
 }
+#endif
 
 int __init construct_hwdom(struct kernel_info *kinfo,
                            const struct dt_device_node *node)
@@ -1954,6 +1962,7 @@ int __init construct_hwdom(struct kernel_info *kinfo,
     return construct_domain(d, kinfo);
 }
 
+#ifdef CONFIG_DOM0_BOOT
 void __init create_dom0(void)
 {
     struct domain *dom0;
@@ -2011,6 +2020,7 @@ void __init create_dom0(void)
 
     set_xs_domain(dom0);
 }
+#endif /* CONFIG_DOM0_BOOT */
 
 /*
  * Local variables:
diff --git a/xen/arch/arm/include/asm/arm64/sve.h b/xen/arch/arm/include/asm/arm64/sve.h
index a71d6a295d..1315063a9d 100644
--- a/xen/arch/arm/include/asm/arm64/sve.h
+++ b/xen/arch/arm/include/asm/arm64/sve.h
@@ -35,7 +35,9 @@ bool sve_domctl_vl_param(int val, unsigned int *out);
 
 #ifdef CONFIG_ARM64_SVE
 
+#ifdef CONFIG_DOM0_BOOT
 extern int opt_dom0_sve;
+#endif
 
 static inline bool is_sve_domain(const struct domain *d)
 {
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 2cd1c021b5..ac282895c2 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -458,11 +458,12 @@ void asmlinkage __init noreturn start_xen(unsigned long fdt_paddr)
 
     do_init_boottests();
 
-    /* Create initial domain 0. */
-    if ( !is_dom0less_mode() )
+    if ( is_dom0less_mode() )
+        printk(XENLOG_INFO "Xen dom0less mode detected\n");
+    else if ( IS_ENABLED(CONFIG_DOM0_BOOT) )
         create_dom0();
     else
-        printk(XENLOG_INFO "Xen dom0less mode detected\n");
+        panic("Neither dom0 nor dom0less mode was detected, aborting\n");
 
     if ( acpi_disabled )
     {
diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig
index e5535ac484..39182f6ce4 100644
--- a/xen/arch/x86/Kconfig
+++ b/xen/arch/x86/Kconfig
@@ -18,6 +18,7 @@ config X86
 	select HAS_COMPAT
 	select HAS_CPUFREQ
 	select HAS_DIT
+	select HAS_DOM0
 	select HAS_EHCI
 	select HAS_EX_TABLE
 	select HAS_FAST_MULTIPLY
diff --git a/xen/common/Kconfig b/xen/common/Kconfig
index 5b289e444f..63735fb83f 100644
--- a/xen/common/Kconfig
+++ b/xen/common/Kconfig
@@ -26,6 +26,16 @@ config DOM0LESS_BOOT
 	  Xen boot without the need of a control domain (Dom0), which could be
 	  present anyway.
 
+config DOM0_BOOT
+	bool "Dom0 boot support" if EXPERT
+	default y
+	depends on HAS_DOM0
+	help
+	  Dom0 boot support enables Xen to boot to the all-powerful domain (Dom0).
+	  If this isn't enabled Xen is expected to boot in dom0less/hyperlaunch
+	  mode only. Currently only Arm respects this option; making x86
+	  respect it is a TODO, potentially as part of the Hyperlaunch work.
+
 config DOMAIN_BUILD_HELPERS
 	bool
 
@@ -125,6 +135,9 @@ config HAS_DEVICE_TREE_DISCOVERY
 	bool
 	select DEVICE_TREE_PARSE
 
+config HAS_DOM0
+	bool
+
 config HAS_DOM0LESS
 	bool
 
@@ -575,6 +588,7 @@ config CMDLINE_OVERRIDE
 
 config DOM0_MEM
 	string "Default value for dom0_mem boot parameter"
+	depends on DOM0_BOOT || X86
 	default ""
 	help
 	  Sets a default value for dom0_mem, e.g. "512M".
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 6b52713518..52c03fc2ad 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -610,6 +610,8 @@ custom_param("extra_guest_irqs", parse_extra_guest_irqs);
 
 #endif /* CONFIG_HAS_PIRQ */
 
+/* Only Arm currently honors CONFIG_DOM0_BOOT. */
+#if !defined(CONFIG_ARM) || defined(CONFIG_DOM0_BOOT)
 static int __init cf_check parse_dom0_param(const char *s)
 {
     const char *ss;
@@ -632,6 +634,7 @@ static int __init cf_check parse_dom0_param(const char *s)
     return rc;
 }
 custom_param("dom0", parse_dom0_param);
+#endif
 
 static void domain_pending_scrub_free(struct domain *d)
 {
diff --git a/xen/common/llc-coloring.c b/xen/common/llc-coloring.c
index b5de5787c1..eb67306b21 100644
--- a/xen/common/llc-coloring.c
+++ b/xen/common/llc-coloring.c
@@ -34,8 +34,10 @@ static unsigned int __ro_after_init max_nr_colors;
 /* Default coloring configuration */
 static unsigned int __ro_after_init default_colors[NR_LLC_COLORS];
 
+#ifdef CONFIG_DOM0_BOOT
 static unsigned int __initdata dom0_colors[NR_LLC_COLORS];
 static unsigned int __initdata dom0_num_colors;
+#endif
 
 static unsigned int __ro_after_init xen_colors[NR_LLC_COLORS];
 static unsigned int __ro_after_init xen_num_colors;
@@ -108,12 +110,14 @@ static int __init parse_color_config(const char *buf, unsigned int colors[],
     return -EINVAL;
 }
 
+#ifdef CONFIG_DOM0_BOOT
 static int __init parse_dom0_colors(const char *s)
 {
     return parse_color_config(s, dom0_colors, ARRAY_SIZE(dom0_colors),
                               &dom0_num_colors);
 }
 custom_param("dom0-llc-colors", parse_dom0_colors);
+#endif
 
 static int __init parse_xen_colors(const char *s)
 {
@@ -243,6 +247,7 @@ void domain_dump_llc_colors(const struct domain *d)
     print_colors(d->llc_colors, d->num_llc_colors);
 }
 
+#ifdef CONFIG_DOM0_BOOT
 int __init dom0_set_llc_colors(struct domain *d)
 {
     typeof(*dom0_colors) *colors;
@@ -267,6 +272,7 @@ int __init dom0_set_llc_colors(struct domain *d)
 
     return 0;
 }
+#endif
 
 int domain_set_llc_colors(struct domain *d,
                           const struct xen_domctl_set_llc_colors *config)
-- 
2.43.0

base-commit: 7e020a4dd6ed30eb6c91a9abe2767034e2bb270a
branch: amoi_dom0_remove6
Re: [PATCH v6] xen/arm, xen/common: Add Kconfig option to control Dom0 boot
Posted by Orzel, Michal 1 day, 17 hours ago

On 02-Nov-26 15:58, Oleksii Moisieiev wrote:
> Introduce HAS_DOM0 and a default-enabled DOM0_BOOT option in common
> Kconfig. Arm and x86 select HAS_DOM0. Expert configurations can disable
> DOM0_BOOT; this patch implements the corresponding code exclusion on Arm.
> Making x86 honor the option remains a TODO, potentially as part of the
> Hyperlaunch work. In particular, x86 still builds and boots its legacy
> Dom0 even if DOM0_BOOT is disabled.
> 
> On Arm, exclude legacy Dom0 creation and its private memory, vCPU, SVE
> and LLC coloring options when DOM0_BOOT is disabled. Hide DOM0_MEM in
> that configuration and disallow ACPI, since the alternative dom0less boot
> path requires device tree. Keep the x86 DOM0_MEM setting and dom0 command
> line parser available until x86 honors DOM0_BOOT.
> 
> Retain the domain and hardware-domain builders, guest SVE and LLC
> coloring support, and Xenstore domain setup: these are also used by
> dom0less guests. This is a switch for legacy Dom0 boot support, not for
> all control-domain or hardware-domain functionality, and it does not
> claim to remove every unreachable path or establish MISRA compliance.
> 
> Check for dom0less mode once in the Arm boot path. Otherwise, create Dom0
> when supported or panic when neither boot mode is available.
> 
> RISC-V does not yet have a legacy Dom0 boot path in this staging tree,
> so it does not select HAS_DOM0.
> 
> Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev@epam.com>
> Acked-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>

although I think it would be nice to update the xen cmdline doc too to mention
that dom0 options depend on this config option like it's done in case of e.g.
llc coloring.

~Michal