aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Dunlap <george.dunlap@eu.citrix.com>2011-04-07 15:40:44 +0100
committerGeorge Dunlap <george.dunlap@eu.citrix.com>2011-04-07 15:40:44 +0100
commit1103c69febefd3a4ce27ad991f16effadeee665f (patch)
tree221d0995da6195b848204d5ff5dc3280fe0434bd
parent5b713d432463659eb64488976a385aa7e64279d9 (diff)
downloadxen-1103c69febefd3a4ce27ad991f16effadeee665f.tar.gz
xen-1103c69febefd3a4ce27ad991f16effadeee665f.tar.bz2
xen-1103c69febefd3a4ce27ad991f16effadeee665f.zip
hvm: infrastructure for backwards-compatible loading
The hvm_save code is used to save and restore hypervisor-related hvm state, either for classic save/restore, or for migration (including remus). This is meant to be backwards-compatible across some hypervisor versions; but if it does change, there is no way to handle the old format as well as the new. This patch introduces the infrastructure to allow a single older version ("compat") of any given "save type" to be defined, along with a function to turn the "old" version into the "new" version. If the size check fails for the "normal" version, it will check the "compat" version, and if it matches, will read the old entry and call the conversion function. This patch involves some preprocessor hackery, but I'm only extending the hackery that's already there. Signed-off-by: George Dunlap <george.dunlap@eu.citrix.com> Acked-by: Tim Deegan <Tim.Deegan@citrix.com> Committed-by: Tim Deegan <Tim.Deegan@citrix.com> xen-unstable changeset: 23171:6a5830de7b54 xen-unstable date: Wed Apr 06 11:40:51 2011 +0100
-rw-r--r--xen/include/public/hvm/save.h26
-rw-r--r--xen/include/xen/hvm/save.h18
2 files changed, 36 insertions, 8 deletions
diff --git a/xen/include/public/hvm/save.h b/xen/include/public/hvm/save.h
index d45f0c1115..8a4c53815a 100644
--- a/xen/include/public/hvm/save.h
+++ b/xen/include/public/hvm/save.h
@@ -61,13 +61,35 @@ struct hvm_save_descriptor {
* ugliness.
*/
-#define DECLARE_HVM_SAVE_TYPE(_x, _code, _type) \
- struct __HVM_SAVE_TYPE_##_x { _type t; char c[_code]; }
+#ifdef __XEN__
+# define DECLARE_HVM_SAVE_TYPE_COMPAT(_x, _code, _type, _ctype, _fix) \
+ static inline int __HVM_SAVE_FIX_COMPAT_##_x(void *h) { return _fix(h); } \
+ struct __HVM_SAVE_TYPE_##_x { _type t; char c[_code]; char cpt[2];}; \
+ struct __HVM_SAVE_TYPE_COMPAT_##_x { _ctype t; }
+
+# define DECLARE_HVM_SAVE_TYPE(_x, _code, _type) \
+ static inline int __HVM_SAVE_FIX_COMPAT_##_x(void *h) { BUG(); return -1; } \
+ struct __HVM_SAVE_TYPE_##_x { _type t; char c[_code]; char cpt[1];}; \
+ struct __HVM_SAVE_TYPE_COMPAT_##_x { _type t; }
+#else
+# define DECLARE_HVM_SAVE_TYPE_COMPAT(_x, _code, _type, _ctype, _fix) \
+ struct __HVM_SAVE_TYPE_##_x { _type t; char c[_code]; char cpt[2];}
+
+# define DECLARE_HVM_SAVE_TYPE(_x, _code, _type) \
+ struct __HVM_SAVE_TYPE_##_x { _type t; char c[_code]; char cpt[1];}
+#endif
#define HVM_SAVE_TYPE(_x) typeof (((struct __HVM_SAVE_TYPE_##_x *)(0))->t)
#define HVM_SAVE_LENGTH(_x) (sizeof (HVM_SAVE_TYPE(_x)))
#define HVM_SAVE_CODE(_x) (sizeof (((struct __HVM_SAVE_TYPE_##_x *)(0))->c))
+#ifdef __XEN__
+# define HVM_SAVE_TYPE_COMPAT(_x) typeof (((struct __HVM_SAVE_TYPE_COMPAT_##_x *)(0))->t)
+# define HVM_SAVE_LENGTH_COMPAT(_x) (sizeof (HVM_SAVE_TYPE_COMPAT(_x)))
+
+# define HVM_SAVE_HAS_COMPAT(_x) (sizeof (((struct __HVM_SAVE_TYPE_##_x *)(0))->cpt)-1)
+# define HVM_SAVE_FIX_COMPAT(_x, _dst) __HVM_SAVE_FIX_COMPAT_##_x(_dst)
+#endif
/*
* The series of save records is teminated by a zero-type, zero-length
diff --git a/xen/include/xen/hvm/save.h b/xen/include/xen/hvm/save.h
index 512311fd55..43adfcf39c 100644
--- a/xen/include/xen/hvm/save.h
+++ b/xen/include/xen/hvm/save.h
@@ -58,13 +58,19 @@ 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, _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)); \
+#define _hvm_load_entry(_x, _h, _dst, _strict) ({ \
+ int r; \
+ if ( (r = _hvm_check_entry((_h), HVM_SAVE_CODE(_x), \
+ HVM_SAVE_LENGTH(_x), (_strict))) == 0 ) \
+ _hvm_read_entry((_h), (_dst), HVM_SAVE_LENGTH(_x)); \
+ else if (HVM_SAVE_HAS_COMPAT(_x) \
+ && (r = _hvm_check_entry((_h), HVM_SAVE_CODE(_x), \
+ HVM_SAVE_LENGTH_COMPAT(_x), (_strict))) == 0 ) { \
+ _hvm_read_entry((_h), (_dst), HVM_SAVE_LENGTH_COMPAT(_x)); \
+ r=HVM_SAVE_FIX_COMPAT(_x, (_dst)); \
+ } \
r; })
+
#define hvm_load_entry(_x, _h, _dst) \
_hvm_load_entry(_x, _h, _dst, 1)
#define hvm_load_entry_zeroextend(_x, _h, _dst) \