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

[RFC 10/38] x86/boot: refactor dom0 page calculation


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: "Daniel P. Smith" <dpsmith@xxxxxxxxxxxxxxxxxxxx>
  • Date: Sat, 19 Apr 2025 18:07:52 -0400
  • Arc-authentication-results: i=1; mx.zohomail.com; dkim=pass header.i=apertussolutions.com; spf=pass smtp.mailfrom=dpsmith@xxxxxxxxxxxxxxxxxxxx; dmarc=pass header.from=<dpsmith@xxxxxxxxxxxxxxxxxxxx>
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1745100530; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=PuW9czx+Smh71kxlwwA/QW0luHAuyQMJevifyYw5t/k=; b=ODQ+J7wMqkVXkGo1ANIcUZ7Rk2YnLRVwnQrJGzIoPUsGONt553R6Fu079lNzWlaoc6z7VlcHZp9JgLIWmahvMwRittuVDs9vqfpsMhd3TDXDPybGv6gKie2bbiXEAIXbg7cm8JSpq1x5DgqcKR+JzFUcAi1tGh46QCYLgqlPrjk=
  • Arc-seal: i=1; a=rsa-sha256; t=1745100530; cv=none; d=zohomail.com; s=zohoarc; b=mQFgns4wlgiFGGcV0I8st8M/lQ28EOzTgXfoj9QLMsh/zr/1N5Y++d0iENcPHzWujNCIyyw4k550kmo5V7GTSWypYxH3pvmZiHmYYhpfWSmQz8dHMv3u6OOOuARIinEPl7ulkkigaEB/UMFrfClNUd4TwL/H38H/jMrrZ8MlUfA=
  • Cc: "Daniel P. Smith" <dpsmith@xxxxxxxxxxxxxxxxxxxx>, jason.andryuk@xxxxxxx, stefano.stabellini@xxxxxxx, agarciav@xxxxxxx, Jan Beulich <jbeulich@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Delivery-date: Sat, 19 Apr 2025 22:10:37 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Caution is needed when dom0 is being constructed as PV using an older kernel
that does not have the elf note XEN_ELFNOTE_INIT_P2M. The logic for handling
this situation is embedded directly and takes into account whether dom0 memory
parameters were specified using the negative allocation syntax. To prepare for
generalizing domain page allocation, isolate this logic to a separate handling
function.

Signed-off-by: Daniel P. Smith <dpsmith@xxxxxxxxxxxxxxxxxxxx>
---
 xen/arch/x86/dom0_build.c | 76 +++++++++++++++++++++------------------
 1 file changed, 41 insertions(+), 35 deletions(-)

diff --git a/xen/arch/x86/dom0_build.c b/xen/arch/x86/dom0_build.c
index 658d81ab598c..a007e424bbe3 100644
--- a/xen/arch/x86/dom0_build.c
+++ b/xen/arch/x86/dom0_build.c
@@ -353,12 +353,50 @@ static void __init calculate_dom0_pages(
     bd->mem_pages = nr_pages;
 }
 
+static void __init dom0_pv_restrict_pages(
+    struct boot_domain *bd, struct elf_dom_parms *parms)
+{
+    if ( (parms->p2m_base == UNSET_ADDR) && !memsize_gt_zero(&dom0_size) &&
+         (!memsize_gt_zero(&dom0_min_size) || (bd->mem_pages > bd->min_pages)) 
)
+    {
+        /*
+         * Legacy Linux kernels (i.e. such without a XEN_ELFNOTE_INIT_P2M
+         * note) require that there is enough virtual space beyond the initial
+         * allocation to set up their initial page tables. This space is
+         * roughly the same size as the p2m table, so make sure the initial
+         * allocation doesn't consume more than about half the space that's
+         * available between params.virt_base and the address space end.
+         */
+        unsigned long vstart, vend, end;
+        unsigned long initrd_len = bd->ramdisk ? bd->ramdisk->size : 0;
+        size_t sizeof_long = is_pv_32bit_domain(bd->d) ? sizeof(int) : 
sizeof(long);
+
+        vstart = parms->virt_base;
+        vend = round_pgup(parms->virt_kend);
+        if ( !parms->unmapped_initrd )
+            vend += round_pgup(initrd_len);
+        end = vend + bd->mem_pages * sizeof_long;
+
+        if ( end > vstart )
+            end += end - vstart;
+        if ( end <= vstart ||
+             (sizeof_long < sizeof(end) && end > (1UL << (8 * sizeof_long))) )
+        {
+            end = sizeof_long >= sizeof(end) ? 0 : 1UL << (8 * sizeof_long);
+            bd->mem_pages = (end - vend) / (2 * sizeof_long);
+            if ( memsize_gt_zero(&dom0_min_size) &&
+                 bd->mem_pages < bd->min_pages )
+                bd->mem_pages = bd->min_pages;
+            printk("Dom0 memory clipped to %lu pages\n", bd->mem_pages);
+        }
+    }
+}
+
 unsigned long __init dom0_compute_nr_pages(
     struct boot_domain *bd, struct elf_dom_parms *parms)
 {
     nodeid_t node;
     struct domain *d = bd->d;
-    unsigned long initrd_len = bd->ramdisk ? bd->ramdisk->size : 0;
     unsigned long avail = 0, iommu_pages = 0;
 
     for_each_node_mask ( node, dom0_nodes )
@@ -404,40 +442,8 @@ unsigned long __init dom0_compute_nr_pages(
     /* Clamp according to min/max limits and available memory (final). */
     calculate_dom0_pages(bd, avail);
 
-    if ( is_pv_domain(d) &&
-         (parms->p2m_base == UNSET_ADDR) && !memsize_gt_zero(&dom0_size) &&
-         (!memsize_gt_zero(&dom0_min_size) || (bd->mem_pages > bd->min_pages)) 
)
-    {
-        /*
-         * Legacy Linux kernels (i.e. such without a XEN_ELFNOTE_INIT_P2M
-         * note) require that there is enough virtual space beyond the initial
-         * allocation to set up their initial page tables. This space is
-         * roughly the same size as the p2m table, so make sure the initial
-         * allocation doesn't consume more than about half the space that's
-         * available between params.virt_base and the address space end.
-         */
-        unsigned long vstart, vend, end;
-        size_t sizeof_long = is_pv_32bit_domain(d) ? sizeof(int) : 
sizeof(long);
-
-        vstart = parms->virt_base;
-        vend = round_pgup(parms->virt_kend);
-        if ( !parms->unmapped_initrd )
-            vend += round_pgup(initrd_len);
-        end = vend + bd->mem_pages * sizeof_long;
-
-        if ( end > vstart )
-            end += end - vstart;
-        if ( end <= vstart ||
-             (sizeof_long < sizeof(end) && end > (1UL << (8 * sizeof_long))) )
-        {
-            end = sizeof_long >= sizeof(end) ? 0 : 1UL << (8 * sizeof_long);
-            bd->mem_pages = (end - vend) / (2 * sizeof_long);
-            if ( memsize_gt_zero(&dom0_min_size) &&
-                 bd->mem_pages < bd->min_pages )
-                bd->mem_pages = bd->min_pages;
-            printk("Dom0 memory clipped to %lu pages\n", bd->mem_pages);
-        }
-    }
+    if ( is_pv_domain(d) )
+        dom0_pv_restrict_pages(bd, parms);
 
     d->max_pages = min_t(unsigned long, bd->max_pages, UINT_MAX);
 
-- 
2.30.2




 


Rackspace

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