[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.