[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [RFC 33/38] x86/boot: refactor bzimage parser to be re-enterant
The bzimage logic uses the unit global orig_image_len to hold the original module length for the kernel when the headroom is calculated. It then uses orig_image_len to locate the start of the bzimage when the expansion is done. This is an issue when more than one bzimage is processed by the headroom calculation logic, as it will leave orig_image_len set to the length of the last bzimage it processed. The boot module work introduced storing the headroom size on a per module basis. By passing in the headroom from the boot module, orig_image_len is no longer needed to locate the beginning of the bzimage after the allocated headroom. The bzimage functions are reworked as such, allowing the removal of orig_image_len and enabling them to be reused by multiple kernel boot modules. Signed-off-by: Daniel P. Smith <dpsmith@xxxxxxxxxxxxxxxxxxxx> --- xen/arch/x86/bzimage.c | 38 ++++++++++++++++++------------ xen/arch/x86/hvm/dom_build.c | 3 ++- xen/arch/x86/include/asm/bzimage.h | 5 ++-- xen/arch/x86/pv/dom0_build.c | 3 ++- 4 files changed, 30 insertions(+), 19 deletions(-) diff --git a/xen/arch/x86/bzimage.c b/xen/arch/x86/bzimage.c index 66f648f311e4..32f0360d25b4 100644 --- a/xen/arch/x86/bzimage.c +++ b/xen/arch/x86/bzimage.c @@ -68,8 +68,6 @@ static __init int bzimage_check(struct setup_header *hdr, unsigned long len) return 1; } -static unsigned long __initdata orig_image_len; - unsigned long __init bzimage_headroom(void *image_start, unsigned long image_length) { @@ -90,7 +88,6 @@ unsigned long __init bzimage_headroom(void *image_start, if ( elf_is_elfbinary(image_start, image_length) ) return 0; - orig_image_len = image_length; headroom = output_length(image_start, image_length); if (gzip_check(image_start, image_length)) { @@ -103,13 +100,20 @@ unsigned long __init bzimage_headroom(void *image_start, return headroom; } -int __init bzimage_parse(void *image_base, void **image_start, - unsigned long *image_len) +int __init bzimage_parse( + void *image_base, void **image_start, unsigned long headroom, + unsigned long *image_len) { struct setup_header *hdr = (struct setup_header *)(*image_start); int err = bzimage_check(hdr, *image_len); - unsigned long output_len; - + unsigned long module_len = *image_len; + + /* + * Variable err will have one of three values: + * - < 0: a error occurred trying to inspect the contents + * - > 0: the image is a bzImage + * - == 0: not a bzImage, could be raw elf or elf.gz (vmlinuz.gz) + */ if ( err < 0 ) return err; @@ -118,21 +122,25 @@ int __init bzimage_parse(void *image_base, void **image_start, *image_start += (hdr->setup_sects + 1) * 512 + hdr->payload_offset; *image_len = hdr->payload_length; } - - if ( elf_is_elfbinary(*image_start, *image_len) ) - return 0; + else + { + if ( elf_is_elfbinary(*image_start, *image_len) ) + return 0; + else + *image_len = *image_len - headroom; + } BUG_ON(!(image_base < *image_start)); - output_len = output_length(*image_start, orig_image_len); - - if ( (err = perform_gunzip(image_base, *image_start, orig_image_len)) > 0 ) - err = decompress(*image_start, orig_image_len, image_base); + if ( (err = perform_gunzip(image_base, *image_start, *image_len)) > 0 ) + err = decompress(*image_start, *image_len, image_base); if ( !err ) { + printk(XENLOG_ERR "%s(%d): decompression failed, reseting image start and len\n", + __func__, err); *image_start = image_base; - *image_len = output_len; + *image_len = module_len; } return err > 0 ? 0 : err; diff --git a/xen/arch/x86/hvm/dom_build.c b/xen/arch/x86/hvm/dom_build.c index a847c2cb16d9..4f614aea34c3 100644 --- a/xen/arch/x86/hvm/dom_build.c +++ b/xen/arch/x86/hvm/dom_build.c @@ -743,7 +743,8 @@ static int __init pvh_load_kernel( struct vcpu *v = d->vcpu[0]; int rc; - if ( (rc = bzimage_parse(image_base, &image_start, &image_len)) != 0 ) + if ( (rc = bzimage_parse(image_base, &image_start, image->headroom, + &image_len)) != 0 ) { printk("Error trying to detect bz compressed kernel\n"); return rc; diff --git a/xen/arch/x86/include/asm/bzimage.h b/xen/arch/x86/include/asm/bzimage.h index 7ed69d39103d..24c7d4b8eb68 100644 --- a/xen/arch/x86/include/asm/bzimage.h +++ b/xen/arch/x86/include/asm/bzimage.h @@ -5,7 +5,8 @@ unsigned long bzimage_headroom(void *image_start, unsigned long image_length); -int bzimage_parse(void *image_base, void **image_start, - unsigned long *image_len); +int bzimage_parse( + void *image_base, void **image_start, unsigned long headroom, + unsigned long *image_len); #endif /* __X86_BZIMAGE_H__ */ diff --git a/xen/arch/x86/pv/dom0_build.c b/xen/arch/x86/pv/dom0_build.c index 8d941ff4486e..8b02f62892d4 100644 --- a/xen/arch/x86/pv/dom0_build.c +++ b/xen/arch/x86/pv/dom0_build.c @@ -427,7 +427,8 @@ static int __init dom0_construct(struct boot_domain *bd) d->max_pages = ~0U; - if ( (rc = bzimage_parse(image_base, &image_start, &image_len)) != 0 ) + if ( (rc = bzimage_parse(image_base, &image_start, bd->kernel->headroom, + &image_len)) != 0 ) return rc; if ( (rc = elf_init(&elf, image_start, image_len)) != 0 ) -- 2.30.2
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |