aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/hvm
diff options
context:
space:
mode:
authorKeir Fraser <keir@xen.org>2010-12-15 10:21:05 +0000
committerKeir Fraser <keir@xen.org>2010-12-15 10:21:05 +0000
commite03284b00e3690bc96e0092dfc248bb6e5290ee4 (patch)
tree10bf3dbffd9d507015ca0a0b7ccce3762650de30 /xen/common/hvm
parent16f40060bcea71509daef897ecb80e91cfbaef99 (diff)
downloadxen-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.c14
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;
}
/*