# HG changeset patch
# User Keir Fraser <keir@xxxxxxx>
# Date 1302187202 -3600
# Node ID bda54dcc8ee10bed91c7e3d2c478acc496f02b8f
# Parent 04607fe48f184466623ad506c6cb1f8807fbfa55
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-unstable changeset: 22524:1f08b2932a52
xen-unstable date: Wed Dec 15 10:21:05 2010 +0000
---
diff -r 04607fe48f18 -r bda54dcc8ee1 xen/arch/x86/hvm/hpet.c
--- a/xen/arch/x86/hvm/hpet.c Thu Apr 07 15:38:58 2011 +0100
+++ b/xen/arch/x86/hvm/hpet.c Thu Apr 07 15:40:02 2011 +0100
@@ -546,7 +546,7 @@
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 04607fe48f18 -r bda54dcc8ee1 xen/common/hvm/save.c
--- a/xen/common/hvm/save.c Thu Apr 07 15:38:58 2011 +0100
+++ b/xen/common/hvm/save.c Thu Apr 07 15:40:02 2011 +0100
@@ -272,7 +272,7 @@
}
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 @@
"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_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 04607fe48f18 -r bda54dcc8ee1 xen/include/xen/hvm/save.h
--- a/xen/include/xen/hvm/save.h Thu Apr 07 15:38:58 2011 +0100
+++ b/xen/include/xen/hvm/save.h Thu Apr 07 15:40:02 2011 +0100
@@ -48,7 +48,7 @@
/* 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 @@
* 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
|