[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


  • To: "Orzel, Michal" <michal.orzel@xxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Oleksii Moisieiev <Oleksii_Moisieiev@xxxxxxxx>
  • Date: Mon, 26 Oct 2026 14:56:51 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=epam.com; dmarc=pass action=none header.from=epam.com; dkim=pass header.d=epam.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=SOMWKkz0ULDbHMNFW8NRN3y9WQvoJjDCfNdHGVKYAkA=; b=xFmoA0xOBFquXuijSSF5g6COn4/319atJA5rZIvNfV7M/ml6eBLne0sVJbhXOVL8oblm/2E6M8/ngoFslJH3omRTlcvPUNGwjDhCdI49ns2uMjmCXc0J4arcirqwJsumefGeLBmbv6cyNVQzoaAY/1cFm0jJ1yBHZ+As3hd/71KRSdw0zBg3g+WodhWrj8tQM3P9RORLqGBPkXqVsNLBpXtp2ENGDULcKGxxiPykeD/vhX33gVcYVDXv8YzWq0M1DiM1chCOrxWAbtXBz0UyFJlzfq91tjg4xDvN0OcMRQI+5KDSsGIGXbH3G9jqt7UuK+OMX1ysEgZ92ndwwYiDiA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=FJZMKEvKB66oK71ApW0FeYed8/ZrESoURDheLPeyoxB4yOJWY2CoHrK3jyxCPWpLmeZFfjdb+I7hOoteuAEznZcNUR5kQ3man4WjFpx/eOVrCCtAoUbfa+ZVAvjtqatwQapJUIjvDQ2y8cSYyvdCVtCaBUDioYW1v6mg3D8B64i7zK5nYEASsKWkPumhIzLyG5WPcboPnh/IGLm3ZRYbjGddajyuyGApT79u64/3Jj2iE29qRfTW04VCE00/fW1XogENWR1VzaS9OkSTaRPtlxV6aeKxQA/eIlNcoQOML9+uwnFmRkwpfS8KaqQ5nElWwpD4LUPvaV5voXI4tPCwlQ==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=epam.com header.i="@epam.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:x-ms-exchange-senderadcheck"
  • Authentication-results: mx.microsoft.com 1; dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=epam.com;
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Anthony PERARD <anthony.perard@xxxxxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Julien Grall <julien@xxxxxxx>, Roger Pau Monné <roger@xxxxxxxxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Teddy Astie <teddy.astie@xxxxxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Delivery-date: Mon, 26 Oct 2026 14:57:00 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHdUnGcfnmLH64VckKy7OjAkXrKMLbwa0mAgB+kSQA=
  • Thread-topic: [PATCH v5] xen/arm, xen/common: Add Kconfig option to control Dom0 boot

Hi Michal,

Thanks for the review. I'm preparing v6 right now. My plans for the 
changes are outlined below.

On 06/10/2026 14:44, Orzel, Michal wrote:
>
> On 02-Oct-26 15:26, 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@xxxxxxxx>
>> Acked-by: Jan Beulich <jbeulich@xxxxxxxx>
>>
>> ---
>>
>> 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.
>>
>> 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.1: "A project shall not contain unreachable code"
> But with this patch you will introduce a lot of unreachable code anyway.

I'm going to remove the statement that the patch eliminates all
unreachable code or establishes MISRA compliance. The description will
instead explain that it excludes legacy Dom0 construction and its
private boot options. Shared domain-building code will remain, since
it is also used by dom0less guests. Is that scope OK?

>> 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        | 13 ++++++++++---
>>   xen/arch/x86/Kconfig        |  1 +
>>   xen/common/Kconfig          | 12 ++++++++++++
>>   5 files changed, 32 insertions(+), 3 deletions(-)
>>
>> diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
>> index 06289005f4..6d0936b353 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
>> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
>> index 72d5316180..cc932d7686 100644
>> --- a/xen/arch/arm/domain_build.c
>> +++ b/xen/arch/arm/domain_build.c
>> @@ -43,8 +43,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
> What about the other dom0-only options: dom0_mem (and CONFIG_DOM0_MEM),
> dom0-llc-colors and dom0=sve?
I'm going to guard Arm's dom0_mem storage and parser with
CONFIG_DOM0_BOOT and make DOM0_MEM depend on DOM0_BOOT || X86. The x86
exception preserves its current behavior until it implements the
option, as discussed in my reply to Jan.

For dom0=sve, I'm going to guard Arm's architecture-specific Dom0
parser and opt_dom0_sve, and exclude the common dom0 parameter
registration on Arm when DOM0_BOOT=n. Guest SVE support will remain
available, and other architectures will keep their existing parser
behavior.

For dom0-llc-colors, I'm going to guard the private Dom0 color arrays
and parameter parser with CONFIG_DOM0_BOOT. Xen coloring and guest
coloring will remain available.
>>   
>>   /*
>>    * If true, the extended regions support is enabled for dom0 and
>> @@ -123,6 +125,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 )
>> @@ -135,6 +138,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.
>> @@ -1862,6 +1866,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)
> This makes dom0_set_llc_colors() unreachable. The same goes for
> prepare_acpi() with ACPI=y, as dom0less is DT only. ACPI should be prevented
> when DOM0_BOOT=n.

I'm going to guard dom0_set_llc_colors() with CONFIG_DOM0_BOOT as well,
while retaining the coloring helpers used by dom0less guests and
runtime domain configuration.

I'm also going to add DOM0_BOOT to the dependencies of Arm's ACPI
option. That prevents ACPI=y when DOM0_BOOT=n and excludes the Arm ACPI
objects, including prepare_acpi(), from those builds. Is that the
separation you had in mind?

>>   {
>>       struct kernel_info kinfo = KERNEL_INFO_INIT;
>> @@ -1893,6 +1898,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)
>> @@ -1944,6 +1950,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;
>> @@ -2001,6 +2008,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 16f899dff5..ea9c037fba 100644
>> --- a/xen/arch/arm/setup.c
>> +++ b/xen/arch/arm/setup.c
>> @@ -491,11 +491,18 @@ void asmlinkage __init noreturn start_xen(unsigned 
>> long fdt_paddr)
>>   
>>       do_init_boottests();
>>   
>> -    /* 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())
> Missing space after () and before )
thank you. will fix.
>> +            printk(XENLOG_INFO "Xen dom0less mode detected\n");
>> +        else
>> +            panic("Neither dom0 nor dom0less mode was detected, 
>> aborting\n");
>> +    }
> To avoid calling is_dom0less_mode() twice, how about:
>
>      if ( is_dom0less_mode() )
>          printk(XENLOG_INFO "Xen dom0less mode detected\n");
>      else if ( IS_ENABLED(CONFIG_DOM0_BOOT) )
>          create_dom0();
>      else
>          panic("Neither dom0 nor dom0less mode was detected, aborting\n");
Thank you for the suggestion. I will use this approach. Will also remove 
extra braces suggested by Jan.
> ~Michal


I have checked the proposed implementation with the four Arm64
DOM0_BOOT/DOM0LESS_BOOT combinations, with SVE and LLC coloring enabled
and ACPI requested. I also checked Arm32 with Dom0 enabled and disabled,
and x86 with both DOM0_BOOT settings.

Best regards,
Oleksii

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.