[Xen-devel] [PATCHv4 0/8] kexec: extend kexec hypercall for use with pv-ops kernels
David Vrabel
david.vrabel at citrix.com
Thu Apr 18 13:38:39 EDT 2013
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
More information about the kexec
mailing list