* 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
* 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) \