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

[PATCH v2 3/7] x86/kexec: add new struct kimage_segment


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Kevin Lampis <kevin.lampis@xxxxxxxxxx>
  • Date: Mon, 22 Jun 2026 16:18:29 +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=X8wWS/QFTT3jxmNODw0M8pTnOtiDA5oLNhuUJci4u7U=; b=AF9WNUB5C9WAJI8HOU0EaE6Y8N81ToKIvwmaAEvL+Yq8estFmkn/gNL0Li05Ph80nmLoGsgK53VQ6LluKCX510wPfgcPucV0uE8+OviGYZFh0gBwv/IB9m+6niU20Byi6GWBKQW4b9rXvfbGkI1cbU3FaVfT2lti28rkZ0DiaeRk9jbGntm9pTR71bLfyaF52gDP6VUa8Pni0JHu2kSfPqzmLEWI1xDUiMZsbNTJBUn+57hZBtx3u4U8WxyoXRGlyJ1QC2B0Rk9Iqw/E8RI9kiGlMvo6pjg3vwtIGlqSJKo/2qKvgOFp+flftu4s6yUAjulUy4zH8dqTX2hn7jdgRg==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=jZgDUZgRu5yd2xo7lyogtHif1/s5+Nd+wTEVTCC6yv7458SR2mNmpzsYkkumLkW5TjzlDF9XFeF7BAETKknkOlFAJZtWM/IP55pJAimaz/m1AbO7preO2hwnR1G4NbuH5C4qykTT/PMbXAvczwsRKvQJmxwC/AVIWo0/ka5gSeVYPhp5uDC0HjADCU2avJdR/0isqA+HmaCfMwpIbgXdX8CJM9OZBpkPGDEmP7Q82N8Tct3hA1nsDINsRMkyxz71melPkmETH2PuNsbNwHBFC9rCnycF21kXRmLgZbxE8EdUX7zm2ZEU0z9RhPBivtYvV29DgoGY8ZA3gGY6/YAfSg==
  • 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@xxxxxxxxxx, Kevin Lampis <kevin.lampis@xxxxxxxxxx>
  • Delivery-date: Mon, 22 Jun 2026 15:17:38 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

From: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>

New struct for internal use because Secure Boot code needs to add an
extra field in a future patch.

Signed-off-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
Signed-off-by: Kevin Lampis <kevin.lampis@xxxxxxxxxx>
---
Changes in v2:
- Read into a local xen_kexec_segment_t variable and fill in segments[i]
  manually instead of casting from a different sized type
- Remove union and _pad from new `struct kimage_segment` type
- Swap xen_kexec_segment_t to struct kimage_segment in separate patch
---
 xen/common/kexec.c       | 19 ++++++++++++++-----
 xen/common/kimage.c      | 25 +++++++++++++------------
 xen/include/xen/kimage.h | 11 +++++++++--
 3 files changed, 36 insertions(+), 19 deletions(-)

diff --git a/xen/common/kexec.c b/xen/common/kexec.c
index f31ab3fa07..5caeb19819 100644
--- a/xen/common/kexec.c
+++ b/xen/common/kexec.c
@@ -920,9 +920,10 @@ static int kexec_load_slot(struct kexec_image *kimage)
 static int kexec_load(XEN_GUEST_HANDLE_PARAM(void) uarg)
 {
     xen_kexec_load_t load;
-    xen_kexec_segment_t *segments;
+    struct kimage_segment *segments;
     struct kexec_image *kimage = NULL;
     int ret;
+    unsigned int i;
 
     if ( copy_from_guest(&load, uarg, 1) )
         return -EFAULT;
@@ -930,14 +931,22 @@ static int kexec_load(XEN_GUEST_HANDLE_PARAM(void) uarg)
     if ( load.nr_segments >= KEXEC_SEGMENT_MAX )
         return -EINVAL;
 
-    segments = xmalloc_array(xen_kexec_segment_t, load.nr_segments);
+    segments = xmalloc_array(struct kimage_segment, load.nr_segments);
     if ( segments == NULL )
         return -ENOMEM;
 
-    if ( copy_from_guest(segments, load.segments.h, load.nr_segments) )
+    for ( i = 0; i < load.nr_segments; i++ )
     {
-        ret = -EFAULT;
-        goto error;
+        xen_kexec_segment_t tmp_seg = {};
+        if ( copy_from_guest_offset(&tmp_seg, load.segments.h, i, 1) )
+        {
+            ret = -EFAULT;
+            goto error;
+        }
+        segments[i].h = tmp_seg.buf.h;
+        segments[i].buf_size = tmp_seg.buf_size;
+        segments[i].dest_maddr = tmp_seg.dest_maddr;
+        segments[i].dest_size = tmp_seg.dest_size;
     }
 
     ret = kimage_alloc(&kimage, load.type, load.arch, load.entry_maddr,
diff --git a/xen/common/kimage.c b/xen/common/kimage.c
index 6e009529ae..dc47306223 100644
--- a/xen/common/kimage.c
+++ b/xen/common/kimage.c
@@ -81,7 +81,7 @@ static struct page_info *kimage_alloc_zeroed_page(unsigned 
memflags)
 
 static int do_kimage_alloc(struct kexec_image **rimage, paddr_t entry,
                            unsigned long nr_segments,
-                           xen_kexec_segment_t *segments, uint8_t type)
+                           struct kimage_segment *segments, uint8_t type)
 {
     struct kexec_image *image;
     unsigned long i;
@@ -206,7 +206,7 @@ out:
 
 static int kimage_normal_alloc(struct kexec_image **rimage, paddr_t entry,
                                unsigned long nr_segments,
-                               xen_kexec_segment_t *segments)
+                               struct kimage_segment *segments)
 {
     return do_kimage_alloc(rimage, entry, nr_segments, segments,
                            KEXEC_TYPE_DEFAULT);
@@ -214,7 +214,7 @@ static int kimage_normal_alloc(struct kexec_image **rimage, 
paddr_t entry,
 
 static int kimage_crash_alloc(struct kexec_image **rimage, paddr_t entry,
                               unsigned long nr_segments,
-                              xen_kexec_segment_t *segments)
+                              struct kimage_segment *segments)
 {
     unsigned long i;
 
@@ -236,7 +236,7 @@ static int kimage_crash_alloc(struct kexec_image **rimage, 
paddr_t entry,
     {
         paddr_t mstart, mend;
 
-        if ( guest_handle_is_null(segments[i].buf.h) )
+        if ( guest_handle_is_null(segments[i].h) )
             continue;
 
         mstart = segments[i].dest_maddr;
@@ -664,7 +664,7 @@ found:
 }
 
 static int kimage_load_normal_segment(struct kexec_image *image,
-                                      xen_kexec_segment_t *segment)
+                                      struct kimage_segment *segment)
 {
     unsigned long to_copy;
     unsigned long src_offset;
@@ -698,7 +698,7 @@ static int kimage_load_normal_segment(struct kexec_image 
*image,
             return ret;
 
         dest_va = __map_domain_page(page);
-        ret = copy_from_guest_offset(dest_va, segment->buf.h, src_offset, 
size);
+        ret = copy_from_guest_offset(dest_va, segment->h, src_offset, size);
         unmap_domain_page(dest_va);
         if ( ret )
             return -EFAULT;
@@ -717,7 +717,7 @@ static int kimage_load_normal_segment(struct kexec_image 
*image,
 }
 
 static int kimage_load_crash_segment(struct kexec_image *image,
-                                     xen_kexec_segment_t *segment)
+                                     struct kimage_segment *segment)
 {
     /*
      * For crash dumps kernels we simply copy the data from user space
@@ -747,7 +747,7 @@ static int kimage_load_crash_segment(struct kexec_image 
*image,
         if ( !dest_va )
             return -EINVAL;
 
-        ret = copy_from_guest_offset(dest_va, segment->buf.h, src_offset, 
schunk);
+        ret = copy_from_guest_offset(dest_va, segment->h, src_offset, schunk);
         memset(dest_va + schunk, 0, dchunk - schunk);
 
         unmap_domain_page(dest_va);
@@ -763,12 +763,13 @@ static int kimage_load_crash_segment(struct kexec_image 
*image,
     return 0;
 }
 
-static int kimage_load_segment(struct kexec_image *image, xen_kexec_segment_t 
*segment)
+static int kimage_load_segment(struct kexec_image *image,
+                               struct kimage_segment *segment)
 {
     int result = -ENOMEM;
     paddr_t addr;
 
-    if ( !guest_handle_is_null(segment->buf.h) )
+    if ( !guest_handle_is_null(segment->h) )
     {
         switch ( image->type )
         {
@@ -794,7 +795,7 @@ static int kimage_load_segment(struct kexec_image *image, 
xen_kexec_segment_t *s
 
 int kimage_alloc(struct kexec_image **rimage, uint8_t type, uint16_t arch,
                  uint64_t entry_maddr,
-                 uint32_t nr_segments, xen_kexec_segment_t *segment)
+                 uint32_t nr_segments, struct kimage_segment *segment)
 {
     int result;
 
@@ -819,7 +820,7 @@ int kimage_alloc(struct kexec_image **rimage, uint8_t type, 
uint16_t arch,
 }
 
 static void kimage_calc_one_digest(struct sha2_256_state *ctx,
-                                   xen_kexec_segment_t *segment)
+                                   struct kimage_segment *segment)
 {
     paddr_t dest;
     unsigned long sbytes;
diff --git a/xen/include/xen/kimage.h b/xen/include/xen/kimage.h
index 8ed89d4fa3..0841b6f321 100644
--- a/xen/include/xen/kimage.h
+++ b/xen/include/xen/kimage.h
@@ -18,12 +18,19 @@
 
 typedef paddr_t kimage_entry_t;
 
+struct kimage_segment {
+    XEN_GUEST_HANDLE(const_void) h;
+    uint64_t buf_size;
+    uint64_t dest_maddr;
+    uint64_t dest_size;
+};
+
 struct kexec_image {
     uint8_t type;
     uint16_t arch;
     uint64_t entry_maddr;
     uint32_t nr_segments;
-    xen_kexec_segment_t *segments;
+    struct kimage_segment *segments;
 
     kimage_entry_t head;
     struct page_info *entry_page;
@@ -44,7 +51,7 @@ struct kexec_image {
 
 int kimage_alloc(struct kexec_image **rimage, uint8_t type, uint16_t arch,
                  uint64_t entry_maddr,
-                 uint32_t nr_segments, xen_kexec_segment_t *segment);
+                 uint32_t nr_segments, struct kimage_segment *segment);
 void kimage_free(struct kexec_image *image);
 int kimage_load_segments(struct kexec_image *image);
 struct page_info *kimage_alloc_control_page(struct kexec_image *image,
-- 
2.52.0




 


Rackspace

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