]> xenbits.xensource.com Git - xen.git/commitdiff
hvm save: Introduce hvm_load_entry_zeroextend().
authorKeir Fraser <keir@xen.org>
Thu, 7 Apr 2011 14:40:02 +0000 (15:40 +0100)
committerKeir Fraser <keir@xen.org>
Thu, 7 Apr 2011 14:40:02 +0000 (15:40 +0100)
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>
xen-unstable changeset:   22524:1f08b2932a52
xen-unstable date:        Wed Dec 15 10:21:05 2010 +0000

xen/arch/x86/hvm/hpet.c
xen/common/hvm/save.c
xen/include/xen/hvm/save.h

index 25acad8e3e27b847a4443da09b85983076c7f5f2..fecfff253e644cc91a6a478cf48cf8fbe9d9c13f 100644 (file)
@@ -546,7 +546,7 @@ static int hpet_load(struct domain *d, hvm_domain_context_t *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;
index 7a312dbfe8cfb3d0a2dc2f54fee1d2ace372ae0b..24c7227e706fedf0e5d8cfdc4278f3cbd5c566f2 100644 (file)
@@ -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;
 }
 
 /*
index 8fc322d6e53ee37410bf9d6586766526d8b40256..512311fd5598640d38b45850c26e75896dc6bf43 100644 (file)
@@ -48,7 +48,7 @@ void _hvm_write_entry(struct hvm_domain_context *h,
 
 /* 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_context *h,
  * 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)