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

[PATCH 4/7] x86/kexec: Support non-page-aligned kexec segments


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Kevin Lampis <kevin.lampis@xxxxxxxxxx>
  • Date: Tue, 9 Jun 2026 16:45:15 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.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=XAGW0A7SKMny7hlVxWXRmaflj5yybevs1GYDnoI4BUI=; b=y8kzUuyNc9qWcLu8yUQwiPa3cCmGwuqOK5HrbQNQ2PFNrX0coV64L5YL3anKhlyo7OSgdBdFqDYG98+ErbwEqJ/GfNIZr4BHHknZGjyBooONiAVCf9R+7p29IAWZqZpY5zOUkvOg4aUPFP6tT4Wxtjp45nnMErDRURJH7p6TFEcBE+9l7DVHISowZ/mmogAeWukUj7nH9ZqpfLmIlTKBFr9zObSzjDqMrh4mwz0UB4JazA4zUYRntAIkVyQnI4M0O92g/CUWaJEwnKJYPPyhNqPqcN9V1iaeSSnGvIQ2KOEj7hESha8wjswyhMKoUAfMEO9sd8gzVukXxZNCic6i+Q==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=wh3BO/RvxfgtaqUYyuMfTwUyvez2TlxN4fOrd41bGFDS9mVH68D31FxHeizRAiS3nR5ycNDKamNPYLOfeAnBAapX9GUds5lsiWqLO5cDiYz2kkVMUeQAwySD6LTMOohc8U9bdnRJbVkNi8CaF24B+y1A9m9YL+LmBS5/KicWrmcz/SGm6GvRcuChZ0jxiniWfp+nOubLJS/8WYTKuhem6v8Sv4jz1vVzQQaS8I+hRetBD1A1T9G32P5DgW8DLqt/SUKNVf/6JVtSZNRW7NKQQWI8UYKK/VXhuSu4XcqORioFWhZCA8N8QLpVjgpKApAVwPh9Y2rNbG+8eD7fu55QNA==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=citrix.com header.i="@citrix.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: jbeulich@xxxxxxxx, andrew.cooper3@xxxxxxxxxx, roger.pau@xxxxxxxxxx, Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>, Kevin Lampis <klampis@xxxxxxxxxx>
  • Delivery-date: Tue, 09 Jun 2026 15:45:02 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

From: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>

With Secure Boot, userspace passes in the entire kernel loaded for verification
purposes. However, the kernel's startup32 function needs to be aligned (e.g. to
16 MiB) and this results in the start of the segment not being page-aligned
(depending on where the startup32 function lands in the kernel binary). Relax
this restriction in Xen to support this use case.

Signed-off-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
Signed-off-by: Kevin Lampis <klampis@xxxxxxxxxx>

---
 xen/common/kimage.c      | 34 ++++++++++++++++++++++++++++++----
 xen/include/xen/kimage.h |  1 +
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/xen/common/kimage.c b/xen/common/kimage.c
index 2c3fd3c3b0..1d872916b9 100644
--- a/xen/common/kimage.c
+++ b/xen/common/kimage.c
@@ -730,12 +730,14 @@ static int kimage_load_crash_segment(struct kexec_image 
*image,
      */
     paddr_t dest;
     unsigned long sbytes, dbytes;
+    unsigned int dest_offset;
     int ret = 0;
     unsigned long src_offset = 0;
 
     sbytes = segment->buf_size;
     dbytes = segment->dest_size;
     dest = segment->dest_maddr;
+    dest_offset = segment->dest_offset;
 
     while ( dbytes )
     {
@@ -745,24 +747,28 @@ static int kimage_load_crash_segment(struct kexec_image 
*image,
 
         dest_mfn = dest >> PAGE_SHIFT;
 
-        dchunk = PAGE_SIZE;
+        dchunk = PAGE_SIZE - dest_offset;
         schunk = min(dchunk, sbytes);
 
         dest_va = map_domain_page(_mfn(dest_mfn));
         if ( !dest_va )
             return -EINVAL;
 
-        ret = copy_from_guest_offset(dest_va, segment->buf.h, src_offset, 
schunk);
+        if ( dest_offset )
+            memset(dest_va, 0, dest_offset);
+        ret = copy_from_guest_offset(dest_va + dest_offset, segment->buf.h,
+                                     src_offset, schunk);
         memset(dest_va + schunk, 0, dchunk - schunk);
 
         unmap_domain_page(dest_va);
         if ( ret )
             return -EFAULT;
 
-        dbytes -= dchunk;
+        dbytes -= dchunk + dest_offset;
         sbytes -= schunk;
-        dest += dchunk;
+        dest += dchunk + dest_offset;
         src_offset += schunk;
+        dest_offset = 0;
     }
 
     return 0;
@@ -803,6 +809,26 @@ int kimage_alloc(struct kexec_image **rimage, uint8_t 
type, uint16_t arch,
                  uint32_t nr_segments, struct kimage_segment *segment)
 {
     int result;
+    unsigned int i;
+
+    for ( i = 0; i < nr_segments; i++ )
+    {
+        paddr_t mend;
+
+        /*
+         * Stash the destination offset-in-page for use when copying the
+         * buffer later.
+         */
+        segment[i].dest_offset = PAGE_OFFSET(segment[i].dest_maddr);
+
+        /*
+         * Align down the start address to page size and align up the end
+         * address to page size.
+         */
+        mend = segment[i].dest_maddr + segment[i].dest_size;
+        segment[i].dest_maddr &= PAGE_MASK;
+        segment[i].dest_size = ROUNDUP(mend, PAGE_SIZE) - 
segment[i].dest_maddr;
+    }
 
     switch( type )
     {
diff --git a/xen/include/xen/kimage.h b/xen/include/xen/kimage.h
index 258349d774..aab8707cac 100644
--- a/xen/include/xen/kimage.h
+++ b/xen/include/xen/kimage.h
@@ -26,6 +26,7 @@ struct kimage_segment {
     uint64_t buf_size;
     uint64_t dest_maddr;
     uint64_t dest_size;
+    unsigned int dest_offset;
 };
 
 struct kexec_image {
-- 
2.52.0




 


Rackspace

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