[Xen-devel] [PATCHv4 0/8] kexec: extend kexec hypercall for use with pv-ops kernels

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

 



On 17/04/13 13:34, Daniel Kiper wrote:
> 
> kexec -e still does not work. I see in my console:
> 
> I'm in purgatory
> sha256 digests do not match :(

I have now fixed this.  Xen was not probably zeroing out trailing pages
(only partial pages) when loading a default image (crash was fine).

The kernel does this by allocating and clearing pages and then
relocating these as normal but it's wasteful to allocate a bunch of
empty pages so I added a IND_ZERO entry type for the indirection pages
which gets the relocation code to zero the destination.

See the kexec-v5 branch at:

http://xenbits.xen.org/gitweb/?p=people/dvrabel/xen.git;a=summary

I shall repost this series again once the 4.4 development window is open.

--- a/xen/arch/x86/x86_64/kexec_reloc.S
+++ b/xen/arch/x86/x86_64/kexec_reloc.S
@@ -130,13 +130,18 @@ relocate_pages:
         jmp     3f
 2:
         testq   $0x8,   %rcx  /* is it the source indicator? */
-        jz      0b            /* Ignore it otherwise */
+        jz      2f
         movq    %rcx,   %rsi  /* For ever source page do a copy */
         andq    $0xfffffffffffff000, %rsi
-
         movq    $512,   %rcx
         rep movsq
-
+        jmp     0b
+2:
+        testq   $0x10,  %rcx  /* is it the zero indicator? */
+        jz      0b            /* Ignore it otherwise */
+        movq    $512,   %rcx  /* Zero the destination page. */
+        xorq    %rax,   %rax
+        rep stosq
         jmp     0b
 3:
         ret
diff --git a/xen/common/kimage.c b/xen/common/kimage.c
index 86261ca..1cc0ef7 100644
--- a/xen/common/kimage.c
+++ b/xen/common/kimage.c
@@ -661,7 +661,7 @@ static int kimage_load_normal_segment(struct
kexec_image *image,
 {
     unsigned long to_copy;
     unsigned long src_offset;
-    paddr_t dest;
+    paddr_t dest, end;
     int ret;

     to_copy = segment->buf_size;
@@ -675,15 +675,13 @@ static int kimage_load_normal_segment(struct
kexec_image *image,
     while ( to_copy )
     {
         unsigned long dest_mfn;
-        size_t dest_off;
         struct page_info *page;
         void *dest_va;
         size_t size;

         dest_mfn = dest >> PAGE_SHIFT;
-        dest_off = dest & ~PAGE_MASK;

-        size = min(PAGE_SIZE - dest_off, to_copy);
+        size = min_t(unsigned long, PAGE_SIZE, to_copy);

         page = kimage_alloc_page(image, dest);
         if ( !page )
@@ -693,16 +691,21 @@ 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 + dest_off, segment->buf,
src_offset, size);
+        ret = copy_from_guest_offset(dest_va, segment->buf, src_offset,
size);
         unmap_domain_page(dest_va);
         if ( ret )
             return -EFAULT;

         to_copy -= size;
         src_offset += size;
-        dest += size;
+        dest += PAGE_SIZE;
     }

+    /* Remainder of the destination should be zeroed. */
+    end = segment->dest_maddr + segment->dest_size;
+    for ( ; dest < end; dest += PAGE_SIZE )
+        kimage_add_entry(image, IND_ZERO);
+
     return 0;
 }

--- a/xen/include/xen/kimage.h
+++ b/xen/include/xen/kimage.h
@@ -14,6 +14,7 @@ typedef paddr_t kimage_entry_t;
 #define IND_INDIRECTION  0x2
 #define IND_DONE         0x4
 #define IND_SOURCE       0x8
+#define IND_ZERO        0x10

 struct kexec_image {
     uint8_t type;

David



[Index of Archives]     [LM Sensors]     [Linux Sound]     [ALSA Users]     [ALSA Devel]     [Linux Audio Users]     [Linux Media]     [Kernel]     [Gimp]     [Yosemite News]     [Linux Media]

  Powered by Linux