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

[PATCH v3] x86/hvm/dom0: fix PVH initrd and metadata placement


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Xenia Ragiadakou <xenia.ragiadakou@xxxxxxx>
  • Date: Tue, 31 Oct 2023 12:26:57 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0)
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; 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=oGl9MqzhP1Oim7igMrrYAJM5bYqCurIVrY6eOC4lji8=; b=Co3z64ksyXuTsbDMdAhBocjJ+VNKAOCUlzPSNSX8AfkQKfM7Yfe62tG2TLU2TMa47yyeHWiNVW8bAqx+6QnWSlPCx7e1p6C1Qlk6qIZJiG56wAETOaaQOkIPT9khVbmsAqsBYwYEuEdYcZuN23gPE2RpIa0oImScfvHCNCYCvjQ7nX3XMX7Jyuo4EVKh0EvqSQvK2wP3KLFZYSvuBncouxU6chQzGURwvji5r2he6Eg3fciwCT/CNJBh/BFjEo8gWOZHvPeASZ0NUS59uIzD0+M5CHq2WIFwTrjFgc+UwpcPX0oTW95hkZTTp1OTJp9FG2CLi7r7GLdgdtcSQj1ZPg==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=dJWnm/cIXK1q/LElyi8mcpcc0KnaC990+eAoS8q68xdHRpzrhwbHuNYGAM+FFmtGY+Xk0T03NPJah3hcxUlfCrx97+J4IYiStzA1Ke+pIpgtUbVhEBHYnsz3v2MBQ2MIXRZT8Ngc1rLtY04ssyJFFENF6npFSQYypLu7DLbmvEERFsINOi5UF9jR1gd56TIbm9DFbo0Z7sTM+xTM3itook4bu1SFjKNJjRBkyJVON4eQ8WzSmh6SEJ3FdRFi1B50queVkhc71a54hY2A0GMO7uVUk9Yl5r6aEukSstuPJiSDaN5bcVCAJ4k7w11Tzz7xLQeU185ya4YRwDM8qBGoCA==
  • Cc: Xenia Ragiadakou <xenia.ragiadakou@xxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>
  • Delivery-date: Tue, 31 Oct 2023 10:28:32 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Zephyr image consists of multiple non-contiguous load segments
that reside in different RAM regions. For instance:
ELF: phdr: paddr=0x1000 memsz=0x8000
ELF: phdr: paddr=0x100000 memsz=0x28a90
ELF: phdr: paddr=0x128aa0 memsz=0x7560
ELF: memory: 0x1000 -> 0x130000

However, the logic that determines the best placement for dom0
initrd and metadata, assumes that the image is fully contained
in a single RAM region, not taking into account the cases where:
(1) start > kernel_start && end > kernel_end
(2) start < kernel_start && end < kernel_end
(3) start > kernel_start && end < kernel_end

In case (1), the evaluation will result in end = kernel_start,
i.e. end < start, and will load initrd in the middle of the kernel.
In case (2), the evaluation will result in start = kernel_end,
i.e. end < start, and will load initrd at kernel_end, that is out
of the memory region under evaluation.
In case (3), the evaluation will result in either end = kernel_start
or start = kernel_end but in both cases will be end < start, and
will either load initrd in the middle of the image, or arbitrarily
at kernel_end.

This patch reorganizes the conditionals to include so far unconsidered
cases as well, uniformly returning the lowest available address.

Fixes: 73b47eea2104 ('x86/dom0: improve PVH initrd and metadata placement')
Signed-off-by: Xenia Ragiadakou <xenia.ragiadakou@xxxxxxx>
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---

Changes in v3:
    - mention Zephyr in commit message (Roger)

Changes in v2:
    - cover further cases of overlap (Jan)
    - mention with an in-code comment that a proper, more fine-grained
      solution can be implemented using a rangeset (Roger)

 xen/arch/x86/hvm/dom0_build.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/xen/arch/x86/hvm/dom0_build.c b/xen/arch/x86/hvm/dom0_build.c
index c7d47d0d4c..62debc7415 100644
--- a/xen/arch/x86/hvm/dom0_build.c
+++ b/xen/arch/x86/hvm/dom0_build.c
@@ -515,16 +515,23 @@ static paddr_t __init find_memory(
 
         ASSERT(IS_ALIGNED(start, PAGE_SIZE) && IS_ALIGNED(end, PAGE_SIZE));
 
+        /*
+         * NB: Even better would be to use rangesets to determine a suitable
+         * range, in particular in case a kernel requests multiple heavily
+         * discontiguous regions (which right now we fold all into one big
+         * region).
+         */
         if ( end <= kernel_start || start >= kernel_end )
-            ; /* No overlap, nothing to do. */
+        {
+            /* No overlap, just check whether the region is large enough. */
+            if ( end - start >= size )
+                return start;
+        }
         /* Deal with the kernel already being loaded in the region. */
-        else if ( kernel_start - start > end - kernel_end )
-            end = kernel_start;
-        else
-            start = kernel_end;
-
-        if ( end - start >= size )
+        else if ( kernel_start > start && kernel_start - start >= size )
             return start;
+        else if ( kernel_end < end && end - kernel_end >= size )
+            return kernel_end;
     }
 
     return INVALID_PADDR;
-- 
2.34.1




 


Rackspace

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