xen/arch/arm/Kconfig | 1 + xen/arch/arm/domain_build.c | 8 ++++++++ xen/arch/arm/setup.c | 14 ++++++++++---- xen/arch/x86/Kconfig | 1 + xen/common/Kconfig | 11 +++++++++++ 5 files changed, 31 insertions(+), 4 deletions(-)
This commit introduces a new Kconfig option, `CONFIG_DOM0_BOOT`, to
allow for building Xen without support for booting a regular domain (Dom0).
This functionality is primarily intended for the ARM architecture.
A new Kconfig symbol, `HAS_DOM0`, has been added and is selected by
default for ARM and X86 architecture. This symbol signifies that an
architecture has the capability to support a Dom0.
The `DOM0_BOOT` option depends on `HAS_DOM0` and defaults to 'y'. For
expert users, this option can be disabled (`CONFIG_EXPERT=y` and no
`CONFIG_DOM0_BOOT` in the config), which will compile out the Dom0
creation code on ARM. This is useful for embedded or dom0less-only
scenarios to reduce binary size and complexity.
The ARM boot path has been updated to panic if it detects a non-dom0less
configuration while `CONFIG_DOM0_BOOT` is disabled, preventing an invalid
boot.
Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev@epam.com>
---
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.
This approach aligns with software quality standards like MISRA C,
which advocate for the removal of unreachable or unnecessary code to
improve safety and maintainability. Specifically, this change helps adhere to:
MISRA C:2012, Rule 2.2: "There shall be no dead code"
In a build configured for a dom0less environment, the code responsible
for creating Dom0 would be considered "dead code" as it would never be
executed. By using the preprocessor to remove it before compilation,
we ensure that the final executable is free from this unreachable
code. This simplifies static analysis, reduces the attack surface,
and makes the codebase easier to verify, which is critical for
systems requiring high levels of safety and security.
---
xen/arch/arm/Kconfig | 1 +
xen/arch/arm/domain_build.c | 8 ++++++++
xen/arch/arm/setup.c | 14 ++++++++++----
xen/arch/x86/Kconfig | 1 +
xen/common/Kconfig | 11 +++++++++++
5 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
index cf6af68299..336b2ed242 100644
--- a/xen/arch/arm/Kconfig
+++ b/xen/arch/arm/Kconfig
@@ -17,6 +17,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_STACK_PROTECTOR
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index fb8fbb1650..62602afc78 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -42,8 +42,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
@@ -104,6 +106,7 @@ int __init parse_arch_dom0_param(const char *s, const char *e)
*/
#define DOM0_FDT_EXTRA_SIZE (128 + sizeof(struct fdt_reserve_entry))
+#ifdef CONFIG_DOM0_BOOT
unsigned int __init dom0_max_vcpus(void)
{
if ( opt_dom0_max_vcpus == 0 )
@@ -116,6 +119,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.
@@ -1962,6 +1966,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;
@@ -1993,6 +1998,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)
@@ -2046,6 +2052,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;
@@ -2103,6 +2110,7 @@ void __init create_dom0(void)
set_xs_domain(dom0);
}
+#endif /* CONFIG_DOM0_BOOT */
/*
* Local variables:
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 7ad870e382..fbb290df60 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -481,12 +481,18 @@ void asmlinkage __init noreturn start_xen(unsigned long fdt_paddr)
enable_errata_workarounds();
enable_cpu_features();
- /* Create initial domain 0. */
- if ( !is_dom0less_mode() )
+ if ( IS_ENABLED(CONFIG_DOM0_BOOT) && !is_dom0less_mode() )
+ {
+ /* Create initial domain 0. */
create_dom0();
+ }
else
- printk(XENLOG_INFO "Xen dom0less mode detected\n");
-
+ {
+ if ( is_dom0less_mode())
+ printk(XENLOG_INFO "Xen dom0less mode detected\n");
+ else
+ panic("Neither dom0 nor dom0less mode was detected, aborting\n");
+ }
if ( acpi_disabled )
{
create_domUs();
diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig
index 3f0f3a0f3a..2aeb361c63 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 76f9ce705f..10a8fc8718 100644
--- a/xen/common/Kconfig
+++ b/xen/common/Kconfig
@@ -26,6 +26,14 @@ 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 (ARM && HAS_DOM0 && HAS_DEVICE_TREE_DISCOVERY && DOMAIN_BUILD_HELPERS) || (X86 && 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 mode only.
+
config DOMAIN_BUILD_HELPERS
bool
@@ -125,6 +133,9 @@ config HAS_DEVICE_TREE_DISCOVERY
bool
select DEVICE_TREE_PARSE
+config HAS_DOM0
+ bool
+
config HAS_DOM0LESS
bool
--
2.34.1
On 24.09.2025 18:00, Oleksii Moisieiev wrote: > --- a/xen/common/Kconfig > +++ b/xen/common/Kconfig > @@ -26,6 +26,14 @@ 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 (ARM && HAS_DOM0 && HAS_DEVICE_TREE_DISCOVERY && DOMAIN_BUILD_HELPERS) || (X86 && HAS_DOM0) This line is too long, and really would have wanted to be broken up anyway. Clearly "depends on HAS_DOM0" can be separated out. I'm not quite sure about the extra Arm-specific dependencies: Are these two really Arm-only (as in: not also affecting e.g. RISC-V)? Furthermore, what if I turned this option off for x86? Doing so would, aiui, have no effect at all right now. An option without any effect imo better wouldn't be exposed. Jan
On 25/09/2025 09:34, Jan Beulich wrote: > On 24.09.2025 18:00, Oleksii Moisieiev wrote: >> --- a/xen/common/Kconfig >> +++ b/xen/common/Kconfig >> @@ -26,6 +26,14 @@ 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 (ARM && HAS_DOM0 && HAS_DEVICE_TREE_DISCOVERY && DOMAIN_BUILD_HELPERS) || (X86 && HAS_DOM0) > This line is too long, and really would have wanted to be broken up anyway. Clearly > "depends on HAS_DOM0" can be separated out. I'm not quite sure about the extra > Arm-specific dependencies: Are these two really Arm-only (as in: not also affecting > e.g. RISC-V)? Furthermore, what if I turned this option off for x86? Doing so would, > aiui, have no effect at all right now. An option without any effect imo better > wouldn't be exposed. My intention was to introduce same behavior for both x86 and arm. Added this config parameter as was stated in the following reply for v1 [0] For now, since hyperlaunch is not merged yet the only option for x86 is Dom0 so it will take no effect for x86 right now. [0]https://lore.kernel.org/xen-devel/9814144b-5eb4-421a-93f3-2a15232a7dd3@suse.com/ > Jan
On 25.09.2025 10:14, Oleksii Moisieiev wrote: > > > On 25/09/2025 09:34, Jan Beulich wrote: >> On 24.09.2025 18:00, Oleksii Moisieiev wrote: >>> --- a/xen/common/Kconfig >>> +++ b/xen/common/Kconfig >>> @@ -26,6 +26,14 @@ 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 (ARM && HAS_DOM0 && HAS_DEVICE_TREE_DISCOVERY && DOMAIN_BUILD_HELPERS) || (X86 && HAS_DOM0) >> This line is too long, and really would have wanted to be broken up anyway. Clearly >> "depends on HAS_DOM0" can be separated out. I'm not quite sure about the extra >> Arm-specific dependencies: Are these two really Arm-only (as in: not also affecting >> e.g. RISC-V)? Furthermore, what if I turned this option off for x86? Doing so would, >> aiui, have no effect at all right now. An option without any effect imo better >> wouldn't be exposed. > My intention was to introduce same behavior for both x86 and arm. > Added this config parameter as was stated in the following reply for v1 [0] No. What I said was "Imo at this point x86 should have this option set to Y unconditionally." That's not what the above construct does. Jan > For now, since hyperlaunch is not merged yet the only option for x86 is > Dom0 so it will > take no effect for x86 right now. > > [0]https://lore.kernel.org/xen-devel/9814144b-5eb4-421a-93f3-2a15232a7dd3@suse.com/ >> Jan
On 24.09.25 19:00, Oleksii Moisieiev wrote: > This commit introduces a new Kconfig option, `CONFIG_DOM0_BOOT`, to > allow for building Xen without support for booting a regular domain (Dom0). > This functionality is primarily intended for the ARM architecture. > > A new Kconfig symbol, `HAS_DOM0`, has been added and is selected by > default for ARM and X86 architecture. This symbol signifies that an > architecture has the capability to support a Dom0. > > The `DOM0_BOOT` option depends on `HAS_DOM0` and defaults to 'y'. For > expert users, this option can be disabled (`CONFIG_EXPERT=y` and no > `CONFIG_DOM0_BOOT` in the config), which will compile out the Dom0 > creation code on ARM. This is useful for embedded or dom0less-only > scenarios to reduce binary size and complexity. > > The ARM boot path has been updated to panic if it detects a non-dom0less > configuration while `CONFIG_DOM0_BOOT` is disabled, preventing an invalid > boot. > > Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev@epam.com> > > --- > > 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. > > This approach aligns with software quality standards like MISRA C, > which advocate for the removal of unreachable or unnecessary code to > improve safety and maintainability. Specifically, this change helps adhere to: > > MISRA C:2012, Rule 2.2: "There shall be no dead code" > > In a build configured for a dom0less environment, the code responsible > for creating Dom0 would be considered "dead code" as it would never be > executed. By using the preprocessor to remove it before compilation, > we ensure that the final executable is free from this unreachable > code. This simplifies static analysis, reduces the attack surface, > and makes the codebase easier to verify, which is critical for > systems requiring high levels of safety and security. > > --- > xen/arch/arm/Kconfig | 1 + > xen/arch/arm/domain_build.c | 8 ++++++++ > xen/arch/arm/setup.c | 14 ++++++++++---- > xen/arch/x86/Kconfig | 1 + > xen/common/Kconfig | 11 +++++++++++ > 5 files changed, 31 insertions(+), 4 deletions(-) > > diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig > index cf6af68299..336b2ed242 100644 > --- a/xen/arch/arm/Kconfig > +++ b/xen/arch/arm/Kconfig > @@ -17,6 +17,7 @@ config ARM > select GENERIC_UART_INIT > select HAS_ALTERNATIVE if HAS_VMAP > select HAS_DEVICE_TREE_DISCOVERY > + select HAS_DOM0 Here HAS_DOM0 is selected and all dependencies also selected ( HAS_DEVICE_TREE_DISCOVERY, DOMAIN_BUILD_HELPERS) > select HAS_DOM0LESS > select HAS_GRANT_CACHE_FLUSH if GRANT_TABLE > select HAS_STACK_PROTECTOR > diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c > index fb8fbb1650..62602afc78 100644 > --- a/xen/arch/arm/domain_build.c > +++ b/xen/arch/arm/domain_build.c > @@ -42,8 +42,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 > @@ -104,6 +106,7 @@ int __init parse_arch_dom0_param(const char *s, const char *e) > */ > #define DOM0_FDT_EXTRA_SIZE (128 + sizeof(struct fdt_reserve_entry)) > > +#ifdef CONFIG_DOM0_BOOT > unsigned int __init dom0_max_vcpus(void) > { > if ( opt_dom0_max_vcpus == 0 ) > @@ -116,6 +119,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. > @@ -1962,6 +1966,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; > @@ -1993,6 +1998,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) > @@ -2046,6 +2052,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; > @@ -2103,6 +2110,7 @@ void __init create_dom0(void) > > set_xs_domain(dom0); > } > +#endif /* CONFIG_DOM0_BOOT */ > > /* > * Local variables: > diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c > index 7ad870e382..fbb290df60 100644 > --- a/xen/arch/arm/setup.c > +++ b/xen/arch/arm/setup.c > @@ -481,12 +481,18 @@ void asmlinkage __init noreturn start_xen(unsigned long fdt_paddr) > enable_errata_workarounds(); > enable_cpu_features(); > > - /* Create initial domain 0. */ > - if ( !is_dom0less_mode() ) > + if ( IS_ENABLED(CONFIG_DOM0_BOOT) && !is_dom0less_mode() ) > + { > + /* Create initial domain 0. */ > create_dom0(); > + } > else > - printk(XENLOG_INFO "Xen dom0less mode detected\n"); > - > + { > + if ( is_dom0less_mode()) > + printk(XENLOG_INFO "Xen dom0less mode detected\n"); > + else > + panic("Neither dom0 nor dom0less mode was detected, aborting\n"); > + } > if ( acpi_disabled ) > { > create_domUs(); > diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig > index 3f0f3a0f3a..2aeb361c63 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 76f9ce705f..10a8fc8718 100644 > --- a/xen/common/Kconfig > +++ b/xen/common/Kconfig > @@ -26,6 +26,14 @@ 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 (ARM && HAS_DOM0 && HAS_DEVICE_TREE_DISCOVERY && DOMAIN_BUILD_HELPERS) || (X86 && HAS_DOM0) Here you repeat the same dependencies. In general, if you introduce HAS_DOM0, which is expected to be selected by ARCH, then all you need is depends on HAS_DOM0 It's ARCH decision to select HAS_DOM0, or not. > + 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 mode only. "is expected to boot and launching all domains in dom0less/Hyperlaunch mode only."? > + > config DOMAIN_BUILD_HELPERS > bool > > @@ -125,6 +133,9 @@ config HAS_DEVICE_TREE_DISCOVERY > bool > select DEVICE_TREE_PARSE > > +config HAS_DOM0 > + bool > + > config HAS_DOM0LESS > bool > -- Best regards, -grygorii
On 25/09/2025 12:22, Grygorii Strashko wrote: > > > On 24.09.25 19:00, Oleksii Moisieiev wrote: >> This commit introduces a new Kconfig option, `CONFIG_DOM0_BOOT`, to >> allow for building Xen without support for booting a regular domain >> (Dom0). >> This functionality is primarily intended for the ARM architecture. >> >> A new Kconfig symbol, `HAS_DOM0`, has been added and is selected by >> default for ARM and X86 architecture. This symbol signifies that an >> architecture has the capability to support a Dom0. >> >> The `DOM0_BOOT` option depends on `HAS_DOM0` and defaults to 'y'. For >> expert users, this option can be disabled (`CONFIG_EXPERT=y` and no >> `CONFIG_DOM0_BOOT` in the config), which will compile out the Dom0 >> creation code on ARM. This is useful for embedded or dom0less-only >> scenarios to reduce binary size and complexity. >> >> The ARM boot path has been updated to panic if it detects a non-dom0less >> configuration while `CONFIG_DOM0_BOOT` is disabled, preventing an >> invalid >> boot. >> >> Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev@epam.com> >> >> --- >> >> 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. >> >> This approach aligns with software quality standards like MISRA C, >> which advocate for the removal of unreachable or unnecessary code to >> improve safety and maintainability. Specifically, this change helps >> adhere to: >> >> MISRA C:2012, Rule 2.2: "There shall be no dead code" >> >> In a build configured for a dom0less environment, the code responsible >> for creating Dom0 would be considered "dead code" as it would never be >> executed. By using the preprocessor to remove it before compilation, >> we ensure that the final executable is free from this unreachable >> code. This simplifies static analysis, reduces the attack surface, >> and makes the codebase easier to verify, which is critical for >> systems requiring high levels of safety and security. >> >> --- >> xen/arch/arm/Kconfig | 1 + >> xen/arch/arm/domain_build.c | 8 ++++++++ >> xen/arch/arm/setup.c | 14 ++++++++++---- >> xen/arch/x86/Kconfig | 1 + >> xen/common/Kconfig | 11 +++++++++++ >> 5 files changed, 31 insertions(+), 4 deletions(-) >> >> diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig >> index cf6af68299..336b2ed242 100644 >> --- a/xen/arch/arm/Kconfig >> +++ b/xen/arch/arm/Kconfig >> @@ -17,6 +17,7 @@ config ARM >> select GENERIC_UART_INIT >> select HAS_ALTERNATIVE if HAS_VMAP >> select HAS_DEVICE_TREE_DISCOVERY >> + select HAS_DOM0 > > Here HAS_DOM0 is selected and all dependencies also selected ( > HAS_DEVICE_TREE_DISCOVERY, DOMAIN_BUILD_HELPERS) > >> select HAS_DOM0LESS >> select HAS_GRANT_CACHE_FLUSH if GRANT_TABLE >> select HAS_STACK_PROTECTOR >> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c >> index fb8fbb1650..62602afc78 100644 >> --- a/xen/arch/arm/domain_build.c >> +++ b/xen/arch/arm/domain_build.c >> @@ -42,8 +42,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 >> @@ -104,6 +106,7 @@ int __init parse_arch_dom0_param(const char *s, >> const char *e) >> */ >> #define DOM0_FDT_EXTRA_SIZE (128 + sizeof(struct fdt_reserve_entry)) >> +#ifdef CONFIG_DOM0_BOOT >> unsigned int __init dom0_max_vcpus(void) >> { >> if ( opt_dom0_max_vcpus == 0 ) >> @@ -116,6 +119,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. >> @@ -1962,6 +1966,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; >> @@ -1993,6 +1998,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) >> @@ -2046,6 +2052,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; >> @@ -2103,6 +2110,7 @@ void __init create_dom0(void) >> set_xs_domain(dom0); >> } >> +#endif /* CONFIG_DOM0_BOOT */ >> /* >> * Local variables: >> diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c >> index 7ad870e382..fbb290df60 100644 >> --- a/xen/arch/arm/setup.c >> +++ b/xen/arch/arm/setup.c >> @@ -481,12 +481,18 @@ void asmlinkage __init noreturn >> start_xen(unsigned long fdt_paddr) >> enable_errata_workarounds(); >> enable_cpu_features(); >> - /* Create initial domain 0. */ >> - if ( !is_dom0less_mode() ) >> + if ( IS_ENABLED(CONFIG_DOM0_BOOT) && !is_dom0less_mode() ) >> + { >> + /* Create initial domain 0. */ >> create_dom0(); >> + } >> else >> - printk(XENLOG_INFO "Xen dom0less mode detected\n"); >> - >> + { >> + if ( is_dom0less_mode()) >> + printk(XENLOG_INFO "Xen dom0less mode detected\n"); >> + else >> + panic("Neither dom0 nor dom0less mode was detected, >> aborting\n"); >> + } >> if ( acpi_disabled ) >> { >> create_domUs(); >> diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig >> index 3f0f3a0f3a..2aeb361c63 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 76f9ce705f..10a8fc8718 100644 >> --- a/xen/common/Kconfig >> +++ b/xen/common/Kconfig >> @@ -26,6 +26,14 @@ 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 (ARM && HAS_DOM0 && HAS_DEVICE_TREE_DISCOVERY && >> DOMAIN_BUILD_HELPERS) || (X86 && HAS_DOM0) > > Here you repeat the same dependencies. In general, if you introduce > HAS_DOM0, > which is expected to be selected by ARCH, then all you need is > > depends on HAS_DOM0 > > It's ARCH decision to select HAS_DOM0, or not. > >> + 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 mode >> only. > > "is expected to boot and launching all domains in dom0less/Hyperlaunch > mode only."? > Thanks for the review. Hyperlauch is not merged right now so I don't think it's a good idea to introduce new term. Agree with other statemets above. >> + >> config DOMAIN_BUILD_HELPERS >> bool >> @@ -125,6 +133,9 @@ config HAS_DEVICE_TREE_DISCOVERY >> bool >> select DEVICE_TREE_PARSE >> +config HAS_DOM0 >> + bool >> + >> config HAS_DOM0LESS >> bool >
On 25.09.25 13:53, Oleksii Moisieiev wrote: > > > On 25/09/2025 12:22, Grygorii Strashko wrote: >> >> >> On 24.09.25 19:00, Oleksii Moisieiev wrote: >>> This commit introduces a new Kconfig option, `CONFIG_DOM0_BOOT`, to >>> allow for building Xen without support for booting a regular domain >>> (Dom0). >>> This functionality is primarily intended for the ARM architecture. >>> >>> A new Kconfig symbol, `HAS_DOM0`, has been added and is selected by >>> default for ARM and X86 architecture. This symbol signifies that an >>> architecture has the capability to support a Dom0. >>> >>> The `DOM0_BOOT` option depends on `HAS_DOM0` and defaults to 'y'. For >>> expert users, this option can be disabled (`CONFIG_EXPERT=y` and no >>> `CONFIG_DOM0_BOOT` in the config), which will compile out the Dom0 >>> creation code on ARM. This is useful for embedded or dom0less-only >>> scenarios to reduce binary size and complexity. >>> >>> The ARM boot path has been updated to panic if it detects a non-dom0less >>> configuration while `CONFIG_DOM0_BOOT` is disabled, preventing an >>> invalid >>> boot. >>> >>> Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev@epam.com> >>> >>> --- >>> >>> 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. >>> >>> This approach aligns with software quality standards like MISRA C, >>> which advocate for the removal of unreachable or unnecessary code to >>> improve safety and maintainability. Specifically, this change helps >>> adhere to: >>> >>> MISRA C:2012, Rule 2.2: "There shall be no dead code" >>> >>> In a build configured for a dom0less environment, the code responsible >>> for creating Dom0 would be considered "dead code" as it would never be >>> executed. By using the preprocessor to remove it before compilation, >>> we ensure that the final executable is free from this unreachable >>> code. This simplifies static analysis, reduces the attack surface, >>> and makes the codebase easier to verify, which is critical for >>> systems requiring high levels of safety and security. >>> >>> --- >>> xen/arch/arm/Kconfig | 1 + >>> xen/arch/arm/domain_build.c | 8 ++++++++ >>> xen/arch/arm/setup.c | 14 ++++++++++---- >>> xen/arch/x86/Kconfig | 1 + >>> xen/common/Kconfig | 11 +++++++++++ >>> 5 files changed, 31 insertions(+), 4 deletions(-) >>> >>> diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig >>> index cf6af68299..336b2ed242 100644 >>> --- a/xen/arch/arm/Kconfig >>> +++ b/xen/arch/arm/Kconfig >>> @@ -17,6 +17,7 @@ config ARM >>> select GENERIC_UART_INIT >>> select HAS_ALTERNATIVE if HAS_VMAP >>> select HAS_DEVICE_TREE_DISCOVERY >>> + select HAS_DOM0 >> >> Here HAS_DOM0 is selected and all dependencies also selected ( >> HAS_DEVICE_TREE_DISCOVERY, DOMAIN_BUILD_HELPERS) >> >>> select HAS_DOM0LESS >>> select HAS_GRANT_CACHE_FLUSH if GRANT_TABLE >>> select HAS_STACK_PROTECTOR >>> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c >>> index fb8fbb1650..62602afc78 100644 >>> --- a/xen/arch/arm/domain_build.c >>> +++ b/xen/arch/arm/domain_build.c >>> @@ -42,8 +42,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 >>> @@ -104,6 +106,7 @@ int __init parse_arch_dom0_param(const char *s, >>> const char *e) >>> */ >>> #define DOM0_FDT_EXTRA_SIZE (128 + sizeof(struct fdt_reserve_entry)) >>> +#ifdef CONFIG_DOM0_BOOT >>> unsigned int __init dom0_max_vcpus(void) >>> { >>> if ( opt_dom0_max_vcpus == 0 ) >>> @@ -116,6 +119,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. >>> @@ -1962,6 +1966,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; >>> @@ -1993,6 +1998,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) >>> @@ -2046,6 +2052,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; >>> @@ -2103,6 +2110,7 @@ void __init create_dom0(void) >>> set_xs_domain(dom0); >>> } >>> +#endif /* CONFIG_DOM0_BOOT */ >>> /* >>> * Local variables: >>> diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c >>> index 7ad870e382..fbb290df60 100644 >>> --- a/xen/arch/arm/setup.c >>> +++ b/xen/arch/arm/setup.c >>> @@ -481,12 +481,18 @@ void asmlinkage __init noreturn >>> start_xen(unsigned long fdt_paddr) >>> enable_errata_workarounds(); >>> enable_cpu_features(); >>> - /* Create initial domain 0. */ >>> - if ( !is_dom0less_mode() ) >>> + if ( IS_ENABLED(CONFIG_DOM0_BOOT) && !is_dom0less_mode() ) >>> + { >>> + /* Create initial domain 0. */ >>> create_dom0(); >>> + } >>> else >>> - printk(XENLOG_INFO "Xen dom0less mode detected\n"); >>> - >>> + { >>> + if ( is_dom0less_mode()) >>> + printk(XENLOG_INFO "Xen dom0less mode detected\n"); >>> + else >>> + panic("Neither dom0 nor dom0less mode was detected, >>> aborting\n"); >>> + } >>> if ( acpi_disabled ) >>> { >>> create_domUs(); >>> diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig >>> index 3f0f3a0f3a..2aeb361c63 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 76f9ce705f..10a8fc8718 100644 >>> --- a/xen/common/Kconfig >>> +++ b/xen/common/Kconfig >>> @@ -26,6 +26,14 @@ 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 (ARM && HAS_DOM0 && HAS_DEVICE_TREE_DISCOVERY && >>> DOMAIN_BUILD_HELPERS) || (X86 && HAS_DOM0) >> >> Here you repeat the same dependencies. In general, if you introduce >> HAS_DOM0, >> which is expected to be selected by ARCH, then all you need is >> >> depends on HAS_DOM0 >> >> It's ARCH decision to select HAS_DOM0, or not. >> >>> + 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 mode >>> only. >> >> "is expected to boot and launching all domains in dom0less/Hyperlaunch >> mode only."? >> > Thanks for the review. Hyperlauch is not merged right now so I don't > think it's a good idea to introduce new term. > Agree with other statemets above. Hyperlauch is partially in "git log --oneline | grep -i hyperl" and hope is to get it in the next version. That's, actually, a good reason to have this option in common and not ARM specific. >>> + >>> config DOMAIN_BUILD_HELPERS >>> bool >>> @@ -125,6 +133,9 @@ config HAS_DEVICE_TREE_DISCOVERY >>> bool >>> select DEVICE_TREE_PARSE >>> +config HAS_DOM0 >>> + bool >>> + >>> config HAS_DOM0LESS >>> bool >> -- Best regards, -grygorii
On 2025-09-24 18:00, Oleksii Moisieiev wrote: > This commit introduces a new Kconfig option, `CONFIG_DOM0_BOOT`, to > allow for building Xen without support for booting a regular domain > (Dom0). > This functionality is primarily intended for the ARM architecture. > > A new Kconfig symbol, `HAS_DOM0`, has been added and is selected by > default for ARM and X86 architecture. This symbol signifies that an > architecture has the capability to support a Dom0. > > The `DOM0_BOOT` option depends on `HAS_DOM0` and defaults to 'y'. For > expert users, this option can be disabled (`CONFIG_EXPERT=y` and no > `CONFIG_DOM0_BOOT` in the config), which will compile out the Dom0 > creation code on ARM. This is useful for embedded or dom0less-only > scenarios to reduce binary size and complexity. > > The ARM boot path has been updated to panic if it detects a > non-dom0less > configuration while `CONFIG_DOM0_BOOT` is disabled, preventing an > invalid > boot. > > Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev@epam.com> > > --- > > 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. > > This approach aligns with software quality standards like MISRA C, > which advocate for the removal of unreachable or unnecessary code to > improve safety and maintainability. Specifically, this change helps > adhere to: > > MISRA C:2012, Rule 2.2: "There shall be no dead code" > > In a build configured for a dom0less environment, the code responsible > for creating Dom0 would be considered "dead code" as it would never be > executed. By using the preprocessor to remove it before compilation, > we ensure that the final executable is free from this unreachable > code. This simplifies static analysis, reduces the attack surface, > and makes the codebase easier to verify, which is critical for > systems requiring high levels of safety and security. > Misra's definition of "dead code" is code that is executed, but can be removed without changing the behavior of the program, while unreachable code is code that is not executed, so I would cite MISRA C Rule 2.1 ("A project shall not contain unreachable code"), rather that R2.2. > --- > xen/arch/arm/Kconfig | 1 + > xen/arch/arm/domain_build.c | 8 ++++++++ > xen/arch/arm/setup.c | 14 ++++++++++---- > xen/arch/x86/Kconfig | 1 + > xen/common/Kconfig | 11 +++++++++++ > 5 files changed, 31 insertions(+), 4 deletions(-) > > diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig > index cf6af68299..336b2ed242 100644 > --- a/xen/arch/arm/Kconfig > +++ b/xen/arch/arm/Kconfig > @@ -17,6 +17,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_STACK_PROTECTOR > diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c > index fb8fbb1650..62602afc78 100644 > --- a/xen/arch/arm/domain_build.c > +++ b/xen/arch/arm/domain_build.c > @@ -42,8 +42,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 > @@ -104,6 +106,7 @@ int __init parse_arch_dom0_param(const char *s, > const char *e) > */ > #define DOM0_FDT_EXTRA_SIZE (128 + sizeof(struct fdt_reserve_entry)) > > +#ifdef CONFIG_DOM0_BOOT > unsigned int __init dom0_max_vcpus(void) > { > if ( opt_dom0_max_vcpus == 0 ) > @@ -116,6 +119,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. > @@ -1962,6 +1966,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; > @@ -1993,6 +1998,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) > @@ -2046,6 +2052,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; > @@ -2103,6 +2110,7 @@ void __init create_dom0(void) > > set_xs_domain(dom0); > } > +#endif /* CONFIG_DOM0_BOOT */ > > /* > * Local variables: > diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c > index 7ad870e382..fbb290df60 100644 > --- a/xen/arch/arm/setup.c > +++ b/xen/arch/arm/setup.c > @@ -481,12 +481,18 @@ void asmlinkage __init noreturn > start_xen(unsigned long fdt_paddr) > enable_errata_workarounds(); > enable_cpu_features(); > > - /* Create initial domain 0. */ > - if ( !is_dom0less_mode() ) > + if ( IS_ENABLED(CONFIG_DOM0_BOOT) && !is_dom0less_mode() ) > + { > + /* Create initial domain 0. */ > create_dom0(); > + } > else > - printk(XENLOG_INFO "Xen dom0less mode detected\n"); > - > + { > + if ( is_dom0less_mode()) > + printk(XENLOG_INFO "Xen dom0less mode detected\n"); > + else > + panic("Neither dom0 nor dom0less mode was detected, > aborting\n"); > + } > if ( acpi_disabled ) > { > create_domUs(); > diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig > index 3f0f3a0f3a..2aeb361c63 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 76f9ce705f..10a8fc8718 100644 > --- a/xen/common/Kconfig > +++ b/xen/common/Kconfig > @@ -26,6 +26,14 @@ 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 (ARM && HAS_DOM0 && HAS_DEVICE_TREE_DISCOVERY && > DOMAIN_BUILD_HELPERS) || (X86 && 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 mode > only. > + > config DOMAIN_BUILD_HELPERS > bool > > @@ -125,6 +133,9 @@ config HAS_DEVICE_TREE_DISCOVERY > bool > select DEVICE_TREE_PARSE > > +config HAS_DOM0 > + bool > + > config HAS_DOM0LESS > bool -- Nicola Vetrini, B.Sc. Software Engineer BUGSENG (https://bugseng.com) LinkedIn: https://www.linkedin.com/in/nicola-vetrini-a42471253
On Wed Sep 24, 2025 at 6:06 PM CEST, Nicola Vetrini wrote: > On 2025-09-24 18:00, Oleksii Moisieiev wrote: >> This commit introduces a new Kconfig option, `CONFIG_DOM0_BOOT`, to >> allow for building Xen without support for booting a regular domain >> (Dom0). >> This functionality is primarily intended for the ARM architecture. >> >> A new Kconfig symbol, `HAS_DOM0`, has been added and is selected by >> default for ARM and X86 architecture. This symbol signifies that an >> architecture has the capability to support a Dom0. >> >> The `DOM0_BOOT` option depends on `HAS_DOM0` and defaults to 'y'. For >> expert users, this option can be disabled (`CONFIG_EXPERT=y` and no >> `CONFIG_DOM0_BOOT` in the config), which will compile out the Dom0 >> creation code on ARM. This is useful for embedded or dom0less-only >> scenarios to reduce binary size and complexity. >> >> The ARM boot path has been updated to panic if it detects a >> non-dom0less >> configuration while `CONFIG_DOM0_BOOT` is disabled, preventing an >> invalid >> boot. >> >> Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev@epam.com> >> >> --- >> >> 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. >> >> This approach aligns with software quality standards like MISRA C, >> which advocate for the removal of unreachable or unnecessary code to >> improve safety and maintainability. Specifically, this change helps >> adhere to: >> >> MISRA C:2012, Rule 2.2: "There shall be no dead code" >> >> In a build configured for a dom0less environment, the code responsible >> for creating Dom0 would be considered "dead code" as it would never be >> executed. By using the preprocessor to remove it before compilation, >> we ensure that the final executable is free from this unreachable >> code. This simplifies static analysis, reduces the attack surface, >> and makes the codebase easier to verify, which is critical for >> systems requiring high levels of safety and security. >> > > Misra's definition of "dead code" is code that is executed, but can be > removed without changing the behavior of the program, while unreachable > code is code that is not executed, so I would cite MISRA C Rule 2.1 ("A > project shall not contain unreachable code"), rather that R2.2. > >> --- >> xen/arch/arm/Kconfig | 1 + >> xen/arch/arm/domain_build.c | 8 ++++++++ >> xen/arch/arm/setup.c | 14 ++++++++++---- >> xen/arch/x86/Kconfig | 1 + >> xen/common/Kconfig | 11 +++++++++++ >> 5 files changed, 31 insertions(+), 4 deletions(-) >> >> diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig >> index cf6af68299..336b2ed242 100644 >> --- a/xen/arch/arm/Kconfig >> +++ b/xen/arch/arm/Kconfig >> @@ -17,6 +17,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_STACK_PROTECTOR >> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c >> index fb8fbb1650..62602afc78 100644 >> --- a/xen/arch/arm/domain_build.c >> +++ b/xen/arch/arm/domain_build.c >> @@ -42,8 +42,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 >> @@ -104,6 +106,7 @@ int __init parse_arch_dom0_param(const char *s, >> const char *e) >> */ >> #define DOM0_FDT_EXTRA_SIZE (128 + sizeof(struct fdt_reserve_entry)) >> >> +#ifdef CONFIG_DOM0_BOOT >> unsigned int __init dom0_max_vcpus(void) >> { >> if ( opt_dom0_max_vcpus == 0 ) >> @@ -116,6 +119,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. >> @@ -1962,6 +1966,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; >> @@ -1993,6 +1998,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) >> @@ -2046,6 +2052,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; >> @@ -2103,6 +2110,7 @@ void __init create_dom0(void) >> >> set_xs_domain(dom0); >> } >> +#endif /* CONFIG_DOM0_BOOT */ >> >> /* >> * Local variables: >> diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c >> index 7ad870e382..fbb290df60 100644 >> --- a/xen/arch/arm/setup.c >> +++ b/xen/arch/arm/setup.c >> @@ -481,12 +481,18 @@ void asmlinkage __init noreturn >> start_xen(unsigned long fdt_paddr) >> enable_errata_workarounds(); >> enable_cpu_features(); >> >> - /* Create initial domain 0. */ >> - if ( !is_dom0less_mode() ) >> + if ( IS_ENABLED(CONFIG_DOM0_BOOT) && !is_dom0less_mode() ) This probably wants inlining in is_dom0less_mode() so every use gets to be resolved statically. >> + { >> + /* Create initial domain 0. */ >> create_dom0(); >> + } >> else >> - printk(XENLOG_INFO "Xen dom0less mode detected\n"); >> - >> + { >> + if ( is_dom0less_mode()) >> + printk(XENLOG_INFO "Xen dom0less mode detected\n"); >> + else >> + panic("Neither dom0 nor dom0less mode was detected, I'd rather have a static check in common code. BUILD_BUG_ON(!CONFIG_DOM0_BOOT && !CONFIG_DOM0LESS_BOOT); >> aborting\n"); >> + } >> if ( acpi_disabled ) >> { >> create_domUs(); >> diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig >> index 3f0f3a0f3a..2aeb361c63 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 76f9ce705f..10a8fc8718 100644 >> --- a/xen/common/Kconfig >> +++ b/xen/common/Kconfig >> @@ -26,6 +26,14 @@ 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 (ARM && HAS_DOM0 && HAS_DEVICE_TREE_DISCOVERY && >> DOMAIN_BUILD_HELPERS) || (X86 && HAS_DOM0) Why not just HAS_DOM0? And why HAS_DEVICE_DISCOVERY and DOMAIN_BUILD_HELPERS? More importantly, why not drop HAS_DOM0 and do "DOM0LESS_BOOT && (X86 || ARM)" instead? Or just HAS_OPTIONAL_DOM0. dom0less is always optional, while dom0 is supported everywhere. HAS_OPTIONAL_DOM0 would signal that a port is capable of compiling out special dom0 construction logic. The current dependency list seems off to me. >> + help >> + Dom0 boot support enables Xen to boot to the all-powerful domain >> (Dom0). ... or the pvshim, in the current x86 code. In time we'll probably want to make it so that !DOM0_BOOT && !DOM0LESS_BOOT && PV_SHIM means PVSHIM_EXCLUSIVE, which would solve the Kconfig headaches we have with it by making all options additive. But as things are today, this includes dom0 and the PV shim. >> + If this isn't enabled Xen is expected to boot in dom0less mode >> only. ... or fail to compile (as per my suggestion above) when dom0less isn't available either. There's an annoying side effect here. randconfig will be able to create a broken config. !DOM0_BOOT && !DOM0LESS_BOOT. CI would need adjusting to keep DOM0_BOOT set in randconfig jobs. I don't have a good solution for that. Cheers, Alejandro
On 26.09.2025 12:53, Alejandro Vallejo wrote: > On Wed Sep 24, 2025 at 6:06 PM CEST, Nicola Vetrini wrote: >> On 2025-09-24 18:00, Oleksii Moisieiev wrote: >>> --- a/xen/arch/arm/setup.c >>> +++ b/xen/arch/arm/setup.c >>> @@ -481,12 +481,18 @@ void asmlinkage __init noreturn >>> start_xen(unsigned long fdt_paddr) >>> enable_errata_workarounds(); >>> enable_cpu_features(); >>> >>> - /* Create initial domain 0. */ >>> - if ( !is_dom0less_mode() ) >>> + if ( IS_ENABLED(CONFIG_DOM0_BOOT) && !is_dom0less_mode() ) > > This probably wants inlining in is_dom0less_mode() so every use gets to be > resolved statically. > >>> + { >>> + /* Create initial domain 0. */ >>> create_dom0(); >>> + } >>> else >>> - printk(XENLOG_INFO "Xen dom0less mode detected\n"); >>> - >>> + { >>> + if ( is_dom0less_mode()) >>> + printk(XENLOG_INFO "Xen dom0less mode detected\n"); >>> + else >>> + panic("Neither dom0 nor dom0less mode was detected, > > I'd rather have a static check in common code. > > BUILD_BUG_ON(!CONFIG_DOM0_BOOT && !CONFIG_DOM0LESS_BOOT); I'd recommend against this, not the least because of the randconfig aspect you mention later. We also allow building (x86) Xen with PV=n and HVM=n, for example. Jan
On 24/09/2025 19:06, Nicola Vetrini wrote: > On 2025-09-24 18:00, Oleksii Moisieiev wrote: >> This commit introduces a new Kconfig option, `CONFIG_DOM0_BOOT`, to >> allow for building Xen without support for booting a regular domain >> (Dom0). >> This functionality is primarily intended for the ARM architecture. >> >> A new Kconfig symbol, `HAS_DOM0`, has been added and is selected by >> default for ARM and X86 architecture. This symbol signifies that an >> architecture has the capability to support a Dom0. >> >> The `DOM0_BOOT` option depends on `HAS_DOM0` and defaults to 'y'. For >> expert users, this option can be disabled (`CONFIG_EXPERT=y` and no >> `CONFIG_DOM0_BOOT` in the config), which will compile out the Dom0 >> creation code on ARM. This is useful for embedded or dom0less-only >> scenarios to reduce binary size and complexity. >> >> The ARM boot path has been updated to panic if it detects a non-dom0less >> configuration while `CONFIG_DOM0_BOOT` is disabled, preventing an >> invalid >> boot. >> >> Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev@epam.com> >> >> --- >> >> 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. >> >> This approach aligns with software quality standards like MISRA C, >> which advocate for the removal of unreachable or unnecessary code to >> improve safety and maintainability. Specifically, this change helps >> adhere to: >> >> MISRA C:2012, Rule 2.2: "There shall be no dead code" >> >> In a build configured for a dom0less environment, the code responsible >> for creating Dom0 would be considered "dead code" as it would never be >> executed. By using the preprocessor to remove it before compilation, >> we ensure that the final executable is free from this unreachable >> code. This simplifies static analysis, reduces the attack surface, >> and makes the codebase easier to verify, which is critical for >> systems requiring high levels of safety and security. >> > > Misra's definition of "dead code" is code that is executed, but can be > removed without changing the behavior of the program, while > unreachable code is code that is not executed, so I would cite MISRA C > Rule 2.1 ("A project shall not contain unreachable code"), rather that > R2.2. > Good point. Thanks alot. >> --- >> xen/arch/arm/Kconfig | 1 + >> xen/arch/arm/domain_build.c | 8 ++++++++ >> xen/arch/arm/setup.c | 14 ++++++++++---- >> xen/arch/x86/Kconfig | 1 + >> xen/common/Kconfig | 11 +++++++++++ >> 5 files changed, 31 insertions(+), 4 deletions(-) >> >> diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig >> index cf6af68299..336b2ed242 100644 >> --- a/xen/arch/arm/Kconfig >> +++ b/xen/arch/arm/Kconfig >> @@ -17,6 +17,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_STACK_PROTECTOR >> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c >> index fb8fbb1650..62602afc78 100644 >> --- a/xen/arch/arm/domain_build.c >> +++ b/xen/arch/arm/domain_build.c >> @@ -42,8 +42,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 >> @@ -104,6 +106,7 @@ int __init parse_arch_dom0_param(const char *s, >> const char *e) >> */ >> #define DOM0_FDT_EXTRA_SIZE (128 + sizeof(struct fdt_reserve_entry)) >> >> +#ifdef CONFIG_DOM0_BOOT >> unsigned int __init dom0_max_vcpus(void) >> { >> if ( opt_dom0_max_vcpus == 0 ) >> @@ -116,6 +119,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. >> @@ -1962,6 +1966,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; >> @@ -1993,6 +1998,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) >> @@ -2046,6 +2052,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; >> @@ -2103,6 +2110,7 @@ void __init create_dom0(void) >> >> set_xs_domain(dom0); >> } >> +#endif /* CONFIG_DOM0_BOOT */ >> >> /* >> * Local variables: >> diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c >> index 7ad870e382..fbb290df60 100644 >> --- a/xen/arch/arm/setup.c >> +++ b/xen/arch/arm/setup.c >> @@ -481,12 +481,18 @@ void asmlinkage __init noreturn >> start_xen(unsigned long fdt_paddr) >> enable_errata_workarounds(); >> enable_cpu_features(); >> >> - /* Create initial domain 0. */ >> - if ( !is_dom0less_mode() ) >> + if ( IS_ENABLED(CONFIG_DOM0_BOOT) && !is_dom0less_mode() ) >> + { >> + /* Create initial domain 0. */ >> create_dom0(); >> + } >> else >> - printk(XENLOG_INFO "Xen dom0less mode detected\n"); >> - >> + { >> + if ( is_dom0less_mode()) >> + printk(XENLOG_INFO "Xen dom0less mode detected\n"); >> + else >> + panic("Neither dom0 nor dom0less mode was detected, >> aborting\n"); >> + } >> if ( acpi_disabled ) >> { >> create_domUs(); >> diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig >> index 3f0f3a0f3a..2aeb361c63 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 76f9ce705f..10a8fc8718 100644 >> --- a/xen/common/Kconfig >> +++ b/xen/common/Kconfig >> @@ -26,6 +26,14 @@ 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 (ARM && HAS_DOM0 && HAS_DEVICE_TREE_DISCOVERY && >> DOMAIN_BUILD_HELPERS) || (X86 && 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 mode >> only. >> + >> config DOMAIN_BUILD_HELPERS >> bool >> >> @@ -125,6 +133,9 @@ config HAS_DEVICE_TREE_DISCOVERY >> bool >> select DEVICE_TREE_PARSE >> >> +config HAS_DOM0 >> + bool >> + >> config HAS_DOM0LESS >> bool >
© 2016 - 2025 Red Hat, Inc.