[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] hvm save: Introduce hvm_load_entry_zeroextend().
# HG changeset patch # User Keir Fraser <keir@xxxxxxx> # Date 1292408465 0 # Node ID 1f08b2932a52fabc0369edd85c7cc1975323fb67 # Parent 6dda9f988ef379e04d9e3fada5d17f0236c6b873 hvm save: Introduce hvm_load_entry_zeroextend(). In certain cases this will allow us to load old HVM save images where an HVM saved chunk has subsequently been extended with new fields. Rather than fail to load the chunk, we can pad the extended structure with zeroes, if the caller knows how to handle that. Signed-off-by: Keir Fraser <keir@xxxxxxx> Acked-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx> --- xen/arch/x86/hvm/hpet.c | 2 +- xen/common/hvm/save.c | 14 ++++++++++---- xen/include/xen/hvm/save.h | 17 +++++++++++------ 3 files changed, 22 insertions(+), 11 deletions(-) diff -r 6dda9f988ef3 -r 1f08b2932a52 xen/arch/x86/hvm/hpet.c --- a/xen/arch/x86/hvm/hpet.c Wed Dec 15 10:15:45 2010 +0000 +++ b/xen/arch/x86/hvm/hpet.c Wed Dec 15 10:21:05 2010 +0000 @@ -546,7 +546,7 @@ static int hpet_load(struct domain *d, h spin_lock(&hp->lock); /* Reload the HPET registers */ - if ( _hvm_check_entry(h, HVM_SAVE_CODE(HPET), HVM_SAVE_LENGTH(HPET)) ) + if ( _hvm_check_entry(h, HVM_SAVE_CODE(HPET), HVM_SAVE_LENGTH(HPET), 1) ) { spin_unlock(&hp->lock); return -EINVAL; diff -r 6dda9f988ef3 -r 1f08b2932a52 xen/common/hvm/save.c --- a/xen/common/hvm/save.c Wed Dec 15 10:15:45 2010 +0000 +++ b/xen/common/hvm/save.c Wed Dec 15 10:21:05 2010 +0000 @@ -272,7 +272,7 @@ void _hvm_write_entry(struct hvm_domain_ } int _hvm_check_entry(struct hvm_domain_context *h, - uint16_t type, uint32_t len) + uint16_t type, uint32_t len, bool_t strict_length) { struct hvm_save_descriptor *d = (struct hvm_save_descriptor *)&h->data[h->cur]; @@ -283,7 +283,8 @@ int _hvm_check_entry(struct hvm_domain_c "for type %u\n", len, type); return -1; } - if ( (type != d->typecode) || (len != d->length) ) + if ( (type != d->typecode) || (len < d->length) || + (strict_length && (len != d->length)) ) { gdprintk(XENLOG_WARNING, "HVM restore mismatch: expected type %u length %u, " @@ -297,8 +298,13 @@ void _hvm_read_entry(struct hvm_domain_c void _hvm_read_entry(struct hvm_domain_context *h, void *dest, uint32_t dest_len) { - memcpy(dest, &h->data[h->cur], dest_len); - h->cur += dest_len; + struct hvm_save_descriptor *d + = (struct hvm_save_descriptor *)&h->data[h->cur - sizeof(*d)]; + BUG_ON(d->length > dest_len); + memcpy(dest, &h->data[h->cur], d->length); + if ( d->length < dest_len ) + memset((char *)dest + d->length, 0, dest_len - d->length); + h->cur += d->length; } /* diff -r 6dda9f988ef3 -r 1f08b2932a52 xen/include/xen/hvm/save.h --- a/xen/include/xen/hvm/save.h Wed Dec 15 10:15:45 2010 +0000 +++ b/xen/include/xen/hvm/save.h Wed Dec 15 10:21:05 2010 +0000 @@ -48,7 +48,7 @@ void _hvm_write_entry(struct hvm_domain_ /* Unmarshalling: test an entry's size and typecode and record the instance */ int _hvm_check_entry(struct hvm_domain_context *h, - uint16_t type, uint32_t len); + uint16_t type, uint32_t len, bool_t strict_length); /* Unmarshalling: copy the contents in a type-safe way */ void _hvm_read_entry(struct hvm_domain_context *h, @@ -58,12 +58,17 @@ void _hvm_read_entry(struct hvm_domain_c * Unmarshalling: check, then copy. Evaluates to zero on success. This load * function requires the save entry to be the same size as the dest structure. */ -#define hvm_load_entry(_x, _h, _dst) ({ \ - int r; \ - r = _hvm_check_entry((_h), HVM_SAVE_CODE(_x), HVM_SAVE_LENGTH(_x)); \ - if ( r == 0 ) \ - _hvm_read_entry((_h), (_dst), HVM_SAVE_LENGTH(_x)); \ +#define _hvm_load_entry(_x, _h, _dst, _strict) ({ \ + int r; \ + r = _hvm_check_entry((_h), HVM_SAVE_CODE(_x), \ + HVM_SAVE_LENGTH(_x), (_strict)); \ + if ( r == 0 ) \ + _hvm_read_entry((_h), (_dst), HVM_SAVE_LENGTH(_x)); \ r; }) +#define hvm_load_entry(_x, _h, _dst) \ + _hvm_load_entry(_x, _h, _dst, 1) +#define hvm_load_entry_zeroextend(_x, _h, _dst) \ + _hvm_load_entry(_x, _h, _dst, 0) /* Unmarshalling: what is the instance ID of the next entry? */ static inline uint16_t hvm_load_instance(struct hvm_domain_context *h) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |