From nobody Mon Jun 8 07:29:46 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1780636922; cv=none; d=zohomail.com; s=zohoarc; b=fxie1yo5VELxHl07C91SX9H372mvWgPvSuyy/l1P1KCbMMwQS8HNSVL9WFay5rbasPWL8Byp9yAHO00BVBz0zJ3uwL2xIjd5hqfG8nhLSQ8utavxdsDQgVtIXlMXjtIucc6bOmdsRr6y7FHxOUJ/YeMUMou6dBwEVZqgPu5pKCs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1780636922; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=AHWDeiNA+imJX8eeXdwKA190eQAUDsJXyCufUuF7d40=; b=CfzPRQOTGglKA0XHc1YmUOF4Xyu1IvjGaKD2cb9IXm6EMAOt1J1tJUzBjcNCp/g4mM57pUNRWN9itduCkhVd+SRTyBLz+hmaFKsNQZTQbTM9KKbtxni8qJmIipuE7426/XSROuvUW4vs/0EYajk4cCaHf6AmaGNqWVIDcVg9dO0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1780636922687520.8115656537382; Thu, 4 Jun 2026 22:22:02 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1328926.1593154 (Exim 4.92) (envelope-from ) id 1wVMzs-0002E9-Sn; Fri, 05 Jun 2026 05:21:32 +0000 Received: by outflank-mailman (output) from mailman id 1328926.1593154; Fri, 05 Jun 2026 05:21:32 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wVMzs-0002E2-QA; Fri, 05 Jun 2026 05:21:32 +0000 Received: by outflank-mailman (input) for mailman id 1328926; Fri, 05 Jun 2026 05:21:31 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wVMzr-000219-JL for xen-devel@lists.xenproject.org; Fri, 05 Jun 2026 05:21:31 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wVMzq-00HJSo-P1 for xen-devel@lists.xenproject.org; Fri, 05 Jun 2026 07:21:30 +0200 Received: from [10.42.69.2] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a225ccc-e002-0a2a0a5209dd-0a2a4502a4c8-16 for ; Fri, 05 Jun 2026 07:21:30 +0200 Received: from [209.85.128.49] (helo=mail-wm1-f49.google.com) by tlsNG-720697.mxtls.expurgate.net with ESMTPS (eXpurgate 4.56.1) (envelope-from ) id 6a225cd9-af86-0a2a45020019-d1558031e0df-3 for ; Fri, 05 Jun 2026 07:21:30 +0200 Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-490be29c1c5so18109435e9.2 for ; Thu, 04 Jun 2026 22:21:30 -0700 (PDT) Received: from EPUAKYIW02F7.. ([45.12.26.204]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-490c2c9ea37sm31922435e9.0.2026.06.04.22.21.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jun 2026 22:21:28 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=20251104 header.d=gmail.com header.i="@gmail.com" header.h="Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780636889; x=1781241689; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=AHWDeiNA+imJX8eeXdwKA190eQAUDsJXyCufUuF7d40=; b=CNfdyksGwx/eDjIbaWsQxgj+RBU546QukOWMhpXhENg0ZemHnGOM0rZTyu6SMFLBws IdQW3JxQrswr3Lf4qTWcp9K98chyFZiLzliLLb0mphnn0zOCr73BXbSixk4PVpp0EWA0 ksMxdPO9pCCjWheP6HXOoK1XycCkAH1nz5e86TcOu0UWPl0w9HBjyqqRBxg2HCSF/jrZ U7cgZcuhhuBk9RHGklrKGwIgV/aaG6NrN+i+IWVAMPTB7fwVxDuTXYr4VZEmH4UzD4Ko D+iym05LjAajhiyNC8srkZ7ExD/a6lbAYCnFvcILpfki7ce9WW0e6zpo+FiTCOkGn0I/ CpeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780636889; x=1781241689; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=AHWDeiNA+imJX8eeXdwKA190eQAUDsJXyCufUuF7d40=; b=AOR8FTcxOQq9DKvqNyIQSqWD7HrfTyomLEWtmoLPnspmLR94RKbFZurg2BNqnJU7w2 Bx669ZY+7sFrllLTUWPCPBb3bulcr85zgwFdsdmKTpaTuW4oluyzsNir1gQMrdmAKbi4 kBn+qK5Z6W2vXjJmFDl4xkqDG3ZMUxb7gQlBAmiSoYuLoA2tZjzlwEJ6Bub8TF72Y78M 5n0oxgts7OG/lYjMg68jNnRJcdwAU6Nn1CVBDsOb7YwhgbexAtc7JihjYeaTRwLudBEq U5QxluJEw2aQOEQpYjejVLy/ILYaoEmQfni+zmrQ/LPo0u7myBprwzUXRz9C82wURboz wZfg== X-Gm-Message-State: AOJu0YwRvXQF6nslO71Eyz4AKIjf2ce9uCPNt7QiUQDHy2fEt3sQNVYi pPc110Y3u6hgD3UYa0MTKQA889cmprLHGR9Ln54RSHeiHCLmEgzNknbGc89qCg== X-Gm-Gg: Acq92OEKeG7DvErlbwF7ZA8MteTup9Q0JwTc/jApXwlKWnfMTQx6bzPz2O2+RhgPbxR Ysk1321j65kQdbZK3aIZ1wwRlbxNoUILzobIwQt78gWcPPR0RcKND5LBlylWw2y8rIa7FsB3V0n 4O+lMmP3KszcCaJaCN3ZtPYM5fIBaEM94+X9niM7hSlGwKT5ydxQtXKgi6+asbc+lluiyMVkBaa aXqgASSzuoKXL2g4DA6RnQ8uTdZr7uEm8INz/mp+kgjKGzFKwmtjuuzhS8zwrVNVb8aeN/BjMdn rXKugSaENdrcsTYCpoiTPqTmJdXjCZJyu/mKK7xTLLk4phHpdDp/vm6ubu6OCSKidTJFPMB+ecM BJauLTI5dZBwMcLgQXtyMAUbCwTWyBIt1O5RPhZtZJBDgEGiDSAkZCxvnplkLGCKlnSLah8XNET Q3i0PVhF+V+W/jhhEFSOfB9/i+BFC90NLw0TUG1A== X-Received: by 2002:a05:600c:524a:b0:490:b11f:2560 with SMTP id 5b1f17b1804b1-490c256f131mr27988045e9.9.1780636889273; Thu, 04 Jun 2026 22:21:29 -0700 (PDT) From: Mykola Kvach To: xen-devel@lists.xenproject.org Cc: Mykola Kvach , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk Subject: [PATCH for-4.22 v2 1/2] xen/arm: split DTB/initrd placement helpers Date: Fri, 5 Jun 2026 08:19:07 +0300 Message-ID: <11537d2b05a6c36d4ba0d852efadeba91d9f6225.1780602987.git.mykola_kvach@epam.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-720697/1780636890-A917D161-7B1E564F/0/0 X-purgate-type: clean X-purgate-size: 10019 X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1780636924491158500 Content-Type: text/plain; charset="utf-8" From: Mykola Kvach The Arm zImage loader currently computes the kernel load address and places the DTB/initrd in one local flow. The hardware-domain memory allocator needs to reuse those placement rules before it chooses bank 0, but open-coding the same calculations there would make the fix harder to audit. Split the existing logic into small helpers: - kernel_zimage_place_in_bank() computes the zImage load address for a given bank. - first_bank_can_fit_modules() checks the aggregate first-bank footprint. - find_dtb_initrd_placement() chooses the DTB/initrd location within a known bank and kernel range. Rename place_modules() to place_dtb_initrd() so the code distinguishes the kernel image from the DTB/initrd placement area. Also update the stale xg_dom_arm.c path in the placement comment. The caller still panics in the same cases as before, so this is intended to be behavior preserving. Signed-off-by: Mykola Kvach Reviewed-by: Michal Orzel --- Changes in v2: - New patch split out from the hardware-domain first-bank fix. - Rename the DTB/initrd placement helpers to avoid treating the kernel and DTB/initrd as the same kind of module. - Pass the RAM end address to find_dtb_initrd_placement() instead of recomputing it from the RAM size. - Update the stale xg_dom_arm.c reference in the placement comment. --- xen/arch/arm/kernel.c | 147 ++++++++++++++++---------- xen/common/device-tree/domain-build.c | 6 +- 2 files changed, 97 insertions(+), 56 deletions(-) diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c index b72585b7fe..d1be4d8074 100644 --- a/xen/arch/arm/kernel.c +++ b/xen/arch/arm/kernel.c @@ -40,27 +40,59 @@ struct minimal_dtb_header { /* There are other fields but we don't use them yet. */ }; =20 -static void __init place_modules(struct kernel_info *info, - paddr_t kernbase, paddr_t kernend) +static paddr_t __init +kernel_zimage_place_in_bank(const struct kernel_info *info, + paddr_t bank_start, paddr_t bank_size) { - /* Align DTB and initrd size to 2Mb. Linux only requires 4 byte alignm= ent */ - const struct boot_module *mod =3D info->bd.initrd; - const struct membanks *mem =3D kernel_info_get_mem(info); - const paddr_t initrd_len =3D ROUNDUP(mod ? mod->size : 0, MB(2)); - const paddr_t dtb_len =3D ROUNDUP(fdt_totalsize(info->fdt), MB(2)); - const paddr_t modsize =3D initrd_len + dtb_len; + paddr_t load_addr; =20 - /* Convenient */ - const paddr_t rambase =3D mem->bank[0].start; - const paddr_t ramsize =3D mem->bank[0].size; - const paddr_t ramend =3D rambase + ramsize; +#ifdef CONFIG_HAS_DOMAIN_TYPE + if ( (info->type =3D=3D DOMAIN_64BIT) && (info->image.start =3D=3D 0) ) + return bank_start + info->image.text_offset; +#endif + + /* + * If start is zero, the zImage is position independent, in this + * case Documentation/arm/Booting recommends loading below 128MiB + * and above 32MiB. Load it as high as possible within these + * constraints, while also avoiding the DTB. + */ + if ( info->image.start =3D=3D 0 ) + { + paddr_t load_end; + + load_end =3D bank_start + bank_size; + load_end =3D MIN(bank_start + MB(128), load_end); + + load_addr =3D load_end - info->image.len; + /* Align to 2MB */ + load_addr &=3D ~(MB(2) - 1); + } + else + load_addr =3D info->image.start; + + return load_addr; +} + +static bool __init first_bank_can_fit_modules(paddr_t ramsize, + paddr_t kernbase, paddr_t ke= rnend, + paddr_t dtb_initrd_size) +{ const paddr_t kernsize =3D ROUNDUP(kernend, MB(2)) - kernbase; - const paddr_t ram128mb =3D rambase + MB(128); =20 - paddr_t modbase; + /* + * Check only the aggregate kernel + DTB/initrd footprint. The actual + * DTB/initrd location is selected by find_dtb_initrd_placement(). + */ + return dtb_initrd_size + kernsize <=3D ramsize; +} =20 - if ( modsize + kernsize > ramsize ) - panic("Not enough memory in the first bank for the kernel+dtb+init= rd\n"); +static bool __init find_dtb_initrd_placement(paddr_t rambase, paddr_t rame= nd, + paddr_t kernbase, paddr_t ker= nend, + paddr_t dtb_initrd_size, + paddr_t *dtb_base) +{ + const paddr_t ram128mb =3D rambase + MB(128); =20 /* * DTB must be loaded such that it does not conflict with the @@ -77,55 +109,64 @@ static void __init place_modules(struct kernel_info *i= nfo, * just before the kernel. * * If changing this then consider - * tools/libxc/xc_dom_arm.c:arch_setup_meminit as well. + * tools/libs/guest/xg_dom_arm.c:meminit as well. */ - if ( ramend >=3D ram128mb + modsize && kernend < ram128mb ) - modbase =3D ram128mb; - else if ( ramend - modsize > ROUNDUP(kernend, MB(2)) ) - modbase =3D ramend - modsize; - else if ( kernbase - rambase > modsize ) - modbase =3D kernbase - modsize; - else + if ( ramend >=3D ram128mb + dtb_initrd_size && kernend < ram128mb ) { - panic("Unable to find suitable location for dtb+initrd\n"); - return; + *dtb_base =3D ram128mb; + return true; } =20 - info->dtb_paddr =3D modbase; - info->initrd_paddr =3D info->dtb_paddr + dtb_len; + if ( ramend - dtb_initrd_size > ROUNDUP(kernend, MB(2)) ) + { + *dtb_base =3D ramend - dtb_initrd_size; + return true; + } + + if ( kernbase - rambase > dtb_initrd_size ) + { + *dtb_base =3D kernbase - dtb_initrd_size; + return true; + } + + return false; } =20 -static paddr_t __init kernel_zimage_place(struct kernel_info *info) +static void __init place_dtb_initrd(struct kernel_info *info, + paddr_t kernbase, paddr_t kernend) { + /* Align DTB and initrd size to 2Mb. Linux only requires 4 byte alignm= ent */ + const struct boot_module *initrd =3D info->bd.initrd; const struct membanks *mem =3D kernel_info_get_mem(info); - paddr_t load_addr; + const paddr_t initrd_len =3D ROUNDUP(initrd ? initrd->size : 0, MB(2)); + const paddr_t dtb_len =3D ROUNDUP(fdt_totalsize(info->fdt), MB(2)); + const paddr_t dtb_initrd_size =3D initrd_len + dtb_len; =20 -#ifdef CONFIG_HAS_DOMAIN_TYPE - if ( (info->type =3D=3D DOMAIN_64BIT) && (info->image.start =3D=3D 0) ) - return mem->bank[0].start + info->image.text_offset; -#endif + /* Convenient */ + const paddr_t rambase =3D mem->bank[0].start; + const paddr_t ramsize =3D mem->bank[0].size; + const paddr_t ramend =3D rambase + ramsize; =20 - /* - * If start is zero, the zImage is position independent, in this - * case Documentation/arm/Booting recommends loading below 128MiB - * and above 32MiB. Load it as high as possible within these - * constraints, while also avoiding the DTB. - */ - if ( info->image.start =3D=3D 0 ) - { - paddr_t load_end; + paddr_t dtb_base; =20 - load_end =3D mem->bank[0].start + mem->bank[0].size; - load_end =3D MIN(mem->bank[0].start + MB(128), load_end); + if ( !first_bank_can_fit_modules(ramsize, kernbase, kernend, + dtb_initrd_size) ) + panic("Not enough memory in the first bank for the kernel+dtb+init= rd\n"); =20 - load_addr =3D load_end - info->image.len; - /* Align to 2MB */ - load_addr &=3D ~((2 << 20) - 1); - } - else - load_addr =3D info->image.start; + if ( !find_dtb_initrd_placement(rambase, ramend, kernbase, kernend, + dtb_initrd_size, &dtb_base) ) + panic("Unable to find suitable location for dtb+initrd\n"); =20 - return load_addr; + info->dtb_paddr =3D dtb_base; + info->initrd_paddr =3D info->dtb_paddr + dtb_len; +} + +static paddr_t __init kernel_zimage_place(struct kernel_info *info) +{ + const struct membanks *mem =3D kernel_info_get_mem(info); + + return kernel_zimage_place_in_bank(info, mem->bank[0].start, + mem->bank[0].size); } =20 static void __init kernel_zimage_load(struct kernel_info *info) @@ -143,7 +184,7 @@ static void __init kernel_zimage_load(struct kernel_inf= o *info) if ( info->entry =3D=3D 0 ) info->entry =3D load_addr; =20 - place_modules(info, load_addr, load_addr + len); + place_dtb_initrd(info, load_addr, load_addr + len); =20 printk("Loading zImage from %"PRIpaddr" to %"PRIpaddr"-%"PRIpaddr"\n", paddr, load_addr, load_addr + len); diff --git a/xen/common/device-tree/domain-build.c b/xen/common/device-tree= /domain-build.c index 2a760b007b..f3ba496f1e 100644 --- a/xen/common/device-tree/domain-build.c +++ b/xen/common/device-tree/domain-build.c @@ -245,8 +245,8 @@ out: * hardware domain to have memory reachable by devices with limited DMA ad= dress * capabilities (e.g. 32-bit DMA). * - * The first bank allocated must be large enough for place_modules() to fit - * the kernel, DTB and initrd. + * The first bank allocated must be large enough for place_dtb_initrd() to + * fit the kernel, DTB and initrd. */ static bool __init allocate_hwdom_memory(struct kernel_info *kinfo) { @@ -302,7 +302,7 @@ static bool __init allocate_hwdom_memory(struct kernel_= info *kinfo) paddr_t bank_size; =20 /* - * The first bank must be large enough for place_modules() to + * The first bank must be large enough for place_dtb_initrd() to * fit the kernel, DTB and initrd. Skip small regions to avoid * ending up with a tiny first bank. */ --=20 2.43.0 From nobody Mon Jun 8 07:29:46 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1780636919; cv=none; d=zohomail.com; s=zohoarc; b=FtaJ1ADg3DdJbj3/eRH/DwtEUFas8JrFb9QUnL88Z4CjyTBqxRy/jgisGEfMlCi8leDSM6ZcytYU5F0mysbcsYGMWkgFNxIY2ye7FgEzfo1TCaqHb6y7hFWqYRgDlA4MPB8FfwbLW5zi9RNdVUsVKXwdickf93AGHDO+Mxra8Z0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1780636919; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ET6rfyTADhmkVbxMEn1N5DcgOf1gJoNvcXXSPP2THsg=; b=AurSefAfBlic50/aBcOWdQ08+EjM3qrJTwR0C9M2SV+AJ/Zdu8cw+ujAx6xPBRFmp5UKl4U4zBIFGmQSN3Wil2SfKpfgavugi+e4KqT0u6eK7k0N49d5nLCwjFru0x/GyKUOziDKFGlTbvIHS+I/0A0V3SC/bwrvsooeRnIsaME= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1780636919423787.4817788094762; Thu, 4 Jun 2026 22:21:59 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1328927.1593165 (Exim 4.92) (envelope-from ) id 1wVMzu-0002RA-89; Fri, 05 Jun 2026 05:21:34 +0000 Received: by outflank-mailman (output) from mailman id 1328927.1593165; Fri, 05 Jun 2026 05:21:34 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wVMzu-0002R3-49; Fri, 05 Jun 2026 05:21:34 +0000 Received: by outflank-mailman (input) for mailman id 1328927; Fri, 05 Jun 2026 05:21:32 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wVMzs-000244-0f for xen-devel@lists.xenproject.org; Fri, 05 Jun 2026 05:21:32 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wVMzr-00HJSo-DJ for xen-devel@lists.xenproject.org; Fri, 05 Jun 2026 07:21:31 +0200 Received: from [10.42.69.8] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a225cd3-e002-0a2a0a5209dd-0a2a4508a7be-6 for ; Fri, 05 Jun 2026 07:21:31 +0200 Received: from [209.85.128.54] (helo=mail-wm1-f54.google.com) by tlsNG-c1860d.mxtls.expurgate.net with ESMTPS (eXpurgate 4.56.1) (envelope-from ) id 6a225cdb-63b5-0a2a45080019-d1558036f133-3 for ; Fri, 05 Jun 2026 07:21:31 +0200 Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-490b64c8311so16943955e9.3 for ; Thu, 04 Jun 2026 22:21:31 -0700 (PDT) Received: from EPUAKYIW02F7.. ([45.12.26.204]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-490c2c9ea37sm31922435e9.0.2026.06.04.22.21.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Jun 2026 22:21:30 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=20251104 header.d=gmail.com header.i="@gmail.com" header.h="Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780636891; x=1781241691; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ET6rfyTADhmkVbxMEn1N5DcgOf1gJoNvcXXSPP2THsg=; b=HTGBF0x5GjhyfSxVPhn2QXJB+2CGuK5rkaPg/dWCQJXw+ialJ/PQKzWBHhkp6CCrev CRwuyevYd/U3NkAkv9ohwU56+2MeqFtmYmE/dE+vXaqnlx+kp0AXaigWbmAiDSkLVQs7 kVZDph9NodW9ny2imOgE6+VZTlZX4Qnm8Jchfb7NG70LoRCk6lwHpJxWcQj2FF7xT4u/ 0H2SA9zhBmv/F9MT5Pa+gcgtAVan8KgJy4SCrMKvS8rK3rcqZNXuko3jnuhCL1igjMho 5umNDwyA71t6MmqSExHFcmGOJYPVL2i9jIhA90rmVYpdbqFTwXNFVNc308pYQ09UU+YH Ll9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780636891; x=1781241691; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=ET6rfyTADhmkVbxMEn1N5DcgOf1gJoNvcXXSPP2THsg=; b=DS5pkuFzU9U6luyFgeCoAXLuiXqbHjqzk1Vvsdvtg78a7RhvufzB6yOf2LpTt60hLr V46dFFJ9sqVSK5m7WFOn3Jjkv/ejLcluMQ7m47kj2Q/d6mGcsUbp3VODAzl8aM9M1OL6 XOWTnLfI7ijF+Wjt3R64RNWWW8p56T2aVKDC2WHXtTJrytPmCJCpa/M8KAIp4ZH2Dw+J XjeWlofkIkAActsVi/nx/J96+JfAlu5sAoUFHOHWYaU0yrUd+yH6shQfNiyi4dmfYYjb vs+jcyBJseCVLc4iy6DPntXFBYy7uY8HXPEOmrLy6d88ZP8toDSSoPCUC3VmDVFxy7xZ eczQ== X-Gm-Message-State: AOJu0Yxn3/w8Fc3vbmDLap+rkV7HROivayngQgUZbKfeVHKAEN5J+7FQ p9zPL3g5hPQ8BgRnF8k8725HEY+W8B+UNjuV9qtzm4f57SdUJNVNydl40Msx5A== X-Gm-Gg: Acq92OG7Ux7zeSsllDY6CBiGRV3NvBbPWwvAQvxXf/mnAawCnUgbQKRigTxshAJ8bcu /0J/TfcFS7P1xky3cOD2UZjzcvPGw4+tr2B6cXZNBBcRFzocG4Dbpx9OHkdhP829JEvrR1qA4MT sCSGW2VfKXJxD9ilGOCMK5LILQgNLEPJuOvk1svd35X+nPPOqkTpwPFU7hvW+cwPRR7eFCy8YpN KGvIiqB+CnNrsoTa/1y2T7VlCnjJ1hfWDBmsx3mDlDW2DvBdvEwJLeUlDLRtrkEZOVg9RE92B2Y S+NK0K3buwVj+Cvt1SWeclHdGBUeDZmnHN1FIMQOn7CfWuX3HBeaz6T9+SS0+RS8ck+h/RZtnGh P/9sDQW0FglYkGWi56oD8Rpcr7lOHcQg2D12qVEY1lhLMVE77kk1XA5K4yp2eLE7WAS38jrVSBS NWZ4d8Op5c1YlShk95yXORZ/Ks4mZrbRSgNN+leg== X-Received: by 2002:a05:600c:82c3:b0:490:9782:3eb8 with SMTP id 5b1f17b1804b1-490c25f4963mr24058725e9.25.1780636890607; Thu, 04 Jun 2026 22:21:30 -0700 (PDT) From: Mykola Kvach To: xen-devel@lists.xenproject.org Cc: Mykola Kvach , Stefano Stabellini , Julien Grall , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , Andrew Cooper , Anthony PERARD , Jan Beulich , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Subject: [PATCH for-4.22 v2 2/2] device-tree: validate hwdom bank 0 boot placement Date: Fri, 5 Jun 2026 08:19:08 +0300 Message-ID: X-Mailer: git-send-email 2.43.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-c1860d/1780636891-B7171DB1-F13DF6DD/0/0 X-purgate-type: clean X-purgate-size: 11838 X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1780636920843158500 Content-Type: text/plain; charset="utf-8" From: Mykola Kvach With LLC coloring enabled, the hardware domain memory is allocated by allocate_hwdom_memory() rather than by using the fixed direct-map layout. Commit de99f3263555 ("device-tree: Improve hwdom memory allocation for DMA") made that allocator prefer lower host regions. The first-bank filter, however, still only checked the old 128MB heuristic. A low region can satisfy that heuristic but still be too small, or otherwise unsuitable, for the hardware-domain kernel and the DTB/initrd area to fit in bank 0 according to the Arm placement rules. Keep the existing first-bank size policy and add an architecture-specific candidate check. On Arm, compute the kernel load address for the candidate bank using the same logic as kernel_zimage_place(), verify that the kernel range is covered by that bank, and then reuse the same DTB/initrd placement helper as place_dtb_initrd(). The FDT is generated later, so use the hardware-domain FDT allocation size as a conservative upper bound for the final DTB size. Check the candidate after capping the host region by the remaining unassigned hardware-domain memory, so the validation is performed against the size that would actually become bank 0. This keeps the DMA-oriented allocation policy from de99f3263555 while preventing a too-small bank 0 from reaching place_dtb_initrd(). Make kernel_zimage_place_in_bank() return INVALID_PADDR when a position-independent zImage cannot be placed in the supplied bank; the real load path turns this into a panic, while the hwdom candidate check uses it to reject the bank. Fixes: de99f3263555 ("device-tree: Improve hwdom memory allocation for DMA") Signed-off-by: Mykola Kvach --- Changes in v2: - Split the behavior-preserving placement refactoring into the previous patch. - Reuse the refactored Arm kernel and DTB/initrd placement helpers for the first-bank candidate check. Link to v1: https://patchew.org/Xen/4f862bb2dc323914b8120b0f16af7516140cf42b.17800651= 03.git.mykola._5Fkvach@epam.com/ Changes since RFC: - Do not keep the RFC scalar minimum-size check. It can both reject valid layouts and accept layouts which still fail later. Instead, validate the candidate bank using the same kernel and DTB/initrd placement rules as the load path. - Replace the scalar minimum-size check with arch_hwdom_first_bank_ok(). - Validate fixed-address and AArch32 start =3D=3D 0 kernel placement against the candidate bank. - Check the candidate after capping the host region by the remaining unassigned hardware-domain memory. - Treat the hardware-domain FDT allocation size as a conservative upper bound because the final FDT is generated later. Link to RFC: https://patchew.org/Xen/9ae4f7dd49f5b1f761193adae573c2675c92e8= 83.1779051035.git.mykola._5Fkvach@epam.com/ Why the RFC scalar approach was not kept: A simple minimum-size check is not sufficient here because the validity of the first bank depends on the actual Arm placement rules, not only on the aggregate size of the kernel, DTB and initrd. The DTB/initrd area may fit before a 64-bit Image loaded with a text offset, while an AArch32 position-independent kernel may leave no valid module location even when the aggregate size appears to fit. Fixed-address kernels also need the candidate bank start to be considered. --- xen/arch/arm/acpi/domain_build.c | 2 - xen/arch/arm/domain_build.c | 8 ++++ xen/arch/arm/include/asm/domain_build.h | 4 ++ xen/arch/arm/include/asm/kernel.h | 9 ++++ xen/arch/arm/kernel.c | 57 ++++++++++++++++++++++++- xen/common/device-tree/domain-build.c | 24 ++++++++--- xen/include/xen/fdt-kernel.h | 9 ++++ 7 files changed, 102 insertions(+), 11 deletions(-) diff --git a/xen/arch/arm/acpi/domain_build.c b/xen/arch/arm/acpi/domain_bu= ild.c index 249d899c33..db16f7fa94 100644 --- a/xen/arch/arm/acpi/domain_build.c +++ b/xen/arch/arm/acpi/domain_build.c @@ -26,8 +26,6 @@ #undef virt_to_mfn #define virt_to_mfn(va) _mfn(__virt_to_mfn(va)) =20 -#define ACPI_DOM0_FDT_MIN_SIZE 4096 - static int __init acpi_iomem_deny_access(struct domain *d) { acpi_status status; diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index 1efddc60ef..550617f152 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -115,6 +115,14 @@ int __init parse_arch_dom0_param(const char *s, const = char *e) (IS_ENABLED(CONFIG_STATIC_SHM) ? \ (NR_SHMEM_BANKS * (160 + 16)) : 0)) =20 +paddr_t __init hwdom_get_fdt_alloc_size(void) +{ + if ( acpi_disabled ) + return fdt_totalsize(device_tree_flattened) + DOM0_FDT_EXTRA_SIZE; + + return ACPI_DOM0_FDT_MIN_SIZE; +} + unsigned int __init dom0_max_vcpus(void) { if ( opt_dom0_max_vcpus =3D=3D 0 ) diff --git a/xen/arch/arm/include/asm/domain_build.h b/xen/arch/arm/include= /asm/domain_build.h index df8b361b3d..85cf46a958 100644 --- a/xen/arch/arm/include/asm/domain_build.h +++ b/xen/arch/arm/include/asm/domain_build.h @@ -19,6 +19,10 @@ int prepare_acpi(struct domain *d, struct kernel_info *k= info); =20 int add_ext_regions(unsigned long s_gfn, unsigned long e_gfn, void *data); =20 +#define ACPI_DOM0_FDT_MIN_SIZE 4096 + +paddr_t hwdom_get_fdt_alloc_size(void); + #if defined(CONFIG_MPU) && defined(CONFIG_ARM_64) /* Utility function to determine if an Armv8-R processor supports VMSA. */ bool has_v8r_vmsa_support(void); diff --git a/xen/arch/arm/include/asm/kernel.h b/xen/arch/arm/include/asm/k= ernel.h index 21f4273fa1..bf14fb208a 100644 --- a/xen/arch/arm/include/asm/kernel.h +++ b/xen/arch/arm/include/asm/kernel.h @@ -8,12 +8,21 @@ =20 #include =20 +#include + +struct kernel_info; + struct arch_kernel_info { /* Enable pl011 emulation */ bool vpl011; }; =20 +#define arch_hwdom_first_bank_ok arch_hwdom_first_bank_ok +bool arch_hwdom_first_bank_ok(const struct kernel_info *info, + paddr_t bank_start, + paddr_t bank_size); + #endif /* #ifdef __ARCH_ARM_KERNEL_H__ */ =20 /* diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c index d1be4d8074..ecea2822a1 100644 --- a/xen/arch/arm/kernel.c +++ b/xen/arch/arm/kernel.c @@ -64,9 +64,15 @@ kernel_zimage_place_in_bank(const struct kernel_info *in= fo, load_end =3D bank_start + bank_size; load_end =3D MIN(bank_start + MB(128), load_end); =20 + if ( load_end - bank_start < info->image.len ) + return INVALID_PADDR; + load_addr =3D load_end - info->image.len; /* Align to 2MB */ load_addr &=3D ~(MB(2) - 1); + + if ( load_addr < bank_start ) + return INVALID_PADDR; } else load_addr =3D info->image.start; @@ -164,9 +170,56 @@ static void __init place_dtb_initrd(struct kernel_info= *info, static paddr_t __init kernel_zimage_place(struct kernel_info *info) { const struct membanks *mem =3D kernel_info_get_mem(info); + paddr_t load_addr; + + load_addr =3D kernel_zimage_place_in_bank(info, mem->bank[0].start, + mem->bank[0].size); + if ( load_addr =3D=3D INVALID_PADDR ) + panic("Unable to find suitable location for the kernel\n"); + + return load_addr; +} + +bool __init arch_hwdom_first_bank_ok(const struct kernel_info *info, + paddr_t bank_start, + paddr_t bank_size) +{ + const struct boot_module *initrd =3D info->bd.initrd; + /* + * place_dtb_initrd() rounds the DTB and initrd placement to 2MB bound= aries; + * use the same granularity when checking whether the first bank can h= old + * them. + */ + const paddr_t initrd_len =3D ROUNDUP(initrd ? initrd->size : 0, MB(2)); + /* + * The hardware domain FDT has not been generated yet. Use the allocat= ion + * size as a conservative upper bound for the final DTB size. + */ + const paddr_t dtb_len =3D ROUNDUP(hwdom_get_fdt_alloc_size(), MB(2)); + const paddr_t rambase =3D bank_start; + const paddr_t ramsize =3D bank_size; + const paddr_t dtb_initrd_size =3D initrd_len + dtb_len; + const paddr_t ramend =3D rambase + ramsize; + paddr_t kernbase; + paddr_t kernend; + paddr_t dtb_base; + + kernbase =3D kernel_zimage_place_in_bank(info, bank_start, bank_size); + if ( kernbase =3D=3D INVALID_PADDR || + info->image.len > INVALID_PADDR - kernbase ) + return false; + + kernend =3D kernbase + info->image.len; + + if ( kernbase < rambase || kernend > ramend ) + return false; + + if ( !first_bank_can_fit_modules(ramsize, kernbase, kernend, + dtb_initrd_size) ) + return false; =20 - return kernel_zimage_place_in_bank(info, mem->bank[0].start, - mem->bank[0].size); + return find_dtb_initrd_placement(rambase, ramend, kernbase, kernend, + dtb_initrd_size, &dtb_base); } =20 static void __init kernel_zimage_load(struct kernel_info *info) diff --git a/xen/common/device-tree/domain-build.c b/xen/common/device-tree= /domain-build.c index f3ba496f1e..2e806c1b09 100644 --- a/xen/common/device-tree/domain-build.c +++ b/xen/common/device-tree/domain-build.c @@ -299,20 +299,30 @@ static bool __init allocate_hwdom_memory(struct kerne= l_info *kinfo) =20 for ( i =3D 0; (kinfo->unassigned_mem > 0) && (i < nr_banks); i++ ) { - paddr_t bank_size; + const paddr_t bank_start =3D hwdom_free_mem->bank[i].start; + paddr_t bank_size =3D hwdom_free_mem->bank[i].size; + + /* + * Check the size that would actually be assigned, not just the si= ze + * of the host region. + */ + bank_size =3D min(bank_size, kinfo->unassigned_mem); =20 /* * The first bank must be large enough for place_dtb_initrd() to * fit the kernel, DTB and initrd. Skip small regions to avoid * ending up with a tiny first bank. */ - if ( !mem->nr_banks && (hwdom_free_mem->bank[i].size < min_bank_si= ze) ) - continue; + if ( !mem->nr_banks ) + { + if ( bank_size < min_bank_size ) + continue; + + if ( !arch_hwdom_first_bank_ok(kinfo, bank_start, bank_size) ) + continue; + } =20 - bank_size =3D MIN(hwdom_free_mem->bank[i].size, kinfo->unassigned_= mem); - if ( !allocate_bank_memory(kinfo, - gaddr_to_gfn(hwdom_free_mem->bank[i].st= art), - bank_size) ) + if ( !allocate_bank_memory(kinfo, gaddr_to_gfn(bank_start), bank_s= ize) ) { xfree(hwdom_free_mem); return false; diff --git a/xen/include/xen/fdt-kernel.h b/xen/include/xen/fdt-kernel.h index 00c37be101..71e2344b97 100644 --- a/xen/include/xen/fdt-kernel.h +++ b/xen/include/xen/fdt-kernel.h @@ -93,6 +93,15 @@ kernel_info_get_mem_const(const struct kernel_info *kinf= o) return container_of(&kinfo->mem.common, const struct membanks, common); } =20 +#ifndef arch_hwdom_first_bank_ok +static inline bool arch_hwdom_first_bank_ok(const struct kernel_info *info, + paddr_t bank_start, + paddr_t bank_size) +{ + return true; +} +#endif + #ifndef KERNEL_INFO_SHM_MEM_INIT =20 #ifdef CONFIG_STATIC_SHM --=20 2.43.0