diff options
author | Keir Fraser <keir@xen.org> | 2010-12-15 10:21:05 +0000 |
---|---|---|
committer | Keir Fraser <keir@xen.org> | 2010-12-15 10:21:05 +0000 |
commit | e03284b00e3690bc96e0092dfc248bb6e5290ee4 (patch) | |
tree | 10bf3dbffd9d507015ca0a0b7ccce3762650de30 /xen/common/hvm | |
parent | 16f40060bcea71509daef897ecb80e91cfbaef99 (diff) | |
download | xen-e03284b00e3690bc96e0092dfc248bb6e5290ee4.tar.gz xen-e03284b00e3690bc96e0092dfc248bb6e5290ee4.tar.bz2 xen-e03284b00e3690bc96e0092dfc248bb6e5290ee4.zip |
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@xen.org>
Acked-by: Tim Deegan <Tim.Deegan@citrix.com>
Diffstat (limited to 'xen/common/hvm')
-rw-r--r-- | xen/common/hvm/save.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/xen/common/hvm/save.c b/xen/common/hvm/save.c index 7a312dbfe8..24c7227e70 100644 --- a/xen/common/hvm/save.c +++ b/xen/common/hvm/save.c @@ -272,7 +272,7 @@ void _hvm_write_entry(struct hvm_domain_context *h, } 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_context *h, "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 @@ int _hvm_check_entry(struct hvm_domain_context *h, 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; } /* |