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

[xen staging] xen/dom0less: Calculate guest DTB size based on MAX_VIRT_CPUS



commit e80f4da85b29f888c0644749b0a4ab29a9f2f6ca
Author:     Oleksandr Tyshchenko <Oleksandr_Tyshchenko@xxxxxxxx>
AuthorDate: Wed Dec 17 08:12:48 2025 +0000
Commit:     Michal Orzel <michal.orzel@xxxxxxx>
CommitDate: Mon Jan 19 12:32:15 2026 +0100

    xen/dom0less: Calculate guest DTB size based on MAX_VIRT_CPUS
    
    Creating a dom0less guest with a high vCPU count (e.g., >32) fails
    because the fixed 4KiB device tree buffer (DOMU_DTB_SIZE) overflows
    during creation.
    
    The FDT nodes for each vCPU are the primary consumer of space,
    and the previous fixed-size buffer was insufficient.
    
    This patch replaces the fixed size with a formula that calculates
    the required buffer size based on a fixed baseline plus a scalable
    portion for each potential vCPU up to the MAX_VIRT_CPUS limit.
    
    Please note, the change to DOMU_DTB_SIZE formula would result in
    a smaller buffer size of 3072 bytes compared to the original 4096 bytes
    on Arm32 platforms where MAX_VIRT_CPUS is 8.
    
    ***
    
    The following tests were done to confirm that the proposed formula
    fits:
    
    1. Arm64 testing with varying vCPU counts (MAX_VIRT_CPUS=128),
       final compacted FDT size:
    
       - 1 vCPU: 1586 bytes (with 18432 byte buffer)
       - 2 vCPUs: 1698 bytes
       - 32 vCPUs: 5058 bytes
       - 128 vCPUs: 15810 bytes
    
    2. Arm64 testing with simulated Arm32 conditions (MAX_VIRT_CPUS=8),
       final compacted FDT size:
    
       - 1 vCPU: 1586 bytes (with 3072 byte buffer)
       - 8 vCPUs: 2370 bytes
    
    3. Arm32 testing (MAX_VIRT_CPUS=8),
       final compacted FDT size:
    
       - 8 vCPUs: 1127 bytes (with 3072 byte buffer)
    
    Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@xxxxxxxx>
    Reviewed-by: Grygorii Strashko <grygorii_strashko@xxxxxxxx>
    Reviewed-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
    Tested-by: Harry Ramsey <harry.ramsey@xxxxxxx>
    Acked-by: Michal Orzel <michal.orzel@xxxxxxx>
    Acked-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
---
 xen/common/device-tree/dom0less-build.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/xen/common/device-tree/dom0less-build.c 
b/xen/common/device-tree/dom0less-build.c
index 495ef7b16a..840d14419d 100644
--- a/xen/common/device-tree/dom0less-build.c
+++ b/xen/common/device-tree/dom0less-build.c
@@ -439,15 +439,25 @@ static int __init domain_handle_dtb_boot_module(struct 
domain *d,
 
 /*
  * The max size for DT is 2MB. However, the generated DT is small (not 
including
- * domU passthrough DT nodes whose size we account separately), 4KB are enough
- * for now, but we might have to increase it in the future.
+ * domU passthrough DT nodes whose size we account separately). The size is
+ * calculated from a fixed baseline plus a scalable portion for each potential
+ * vCPU node up to the system limit (MAX_VIRT_CPUS), as the vCPU nodes are
+ * the primary consumer of space.
+ *
+ * The baseline of 2KiB is a safe buffer for all non-vCPU FDT content.
+ * Empirical testing with the maximum number of other device tree nodes shows
+ * a final compacted base size of ~1.5KiB. The 128 bytes per vCPU is derived
+ * from a worst-case analysis of the FDT construction-time size for a single
+ * vCPU node.
  */
-#define DOMU_DTB_SIZE 4096
+#define DOMU_DTB_SIZE (2048 + (MAX_VIRT_CPUS * 128))
 static int __init prepare_dtb_domU(struct domain *d, struct kernel_info *kinfo)
 {
     int addrcells, sizecells;
     int ret, fdt_size = DOMU_DTB_SIZE;
 
+    BUILD_BUG_ON(DOMU_DTB_SIZE > SZ_2M);
+
     kinfo->phandle_intc = GUEST_PHANDLE_GIC;
 
 #ifdef CONFIG_GRANT_TABLE
--
generated by git-patchbot for /home/xen/git/xen.git#staging



 


Rackspace

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