aboutsummaryrefslogtreecommitdiffstats
path: root/xen/include/xen/shared.h
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-03-16 14:11:34 +0000
committerKeir Fraser <keir.fraser@citrix.com>2008-03-16 14:11:34 +0000
commit33c8483360bba3536dc678a94e7f70cb75828066 (patch)
tree96762b4f3dc117f35580f54b3c7e1d63db0b4f1d /xen/include/xen/shared.h
parent266a06100af5272c956bf7dba719b0b823647a5b (diff)
downloadxen-33c8483360bba3536dc678a94e7f70cb75828066.tar.gz
xen-33c8483360bba3536dc678a94e7f70cb75828066.tar.bz2
xen-33c8483360bba3536dc678a94e7f70cb75828066.zip
x86: Allow bitop functions to be applied only to fields of at least 4
bytes. Otherwise the 'longword' processor instructions used will overlap with adjacent fields with unpredictable consequences. This change requires some code fixup and just a few casts (mainly when operating on guest-shared fields which cannot be changed, and which by observation are clearly safe). Based on ideas from Jan Beulich <jbeulich@novell.com> Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Diffstat (limited to 'xen/include/xen/shared.h')
-rw-r--r--xen/include/xen/shared.h36
1 files changed, 14 insertions, 22 deletions
diff --git a/xen/include/xen/shared.h b/xen/include/xen/shared.h
index 216d72116d..9738a49621 100644
--- a/xen/include/xen/shared.h
+++ b/xen/include/xen/shared.h
@@ -12,44 +12,36 @@ typedef union {
struct compat_shared_info compat;
} shared_info_t;
-#define __shared_info(d, s, field) (*(!has_32bit_shinfo(d) ? \
- &(s)->native.field : \
- &(s)->compat.field))
-#define __shared_info_addr(d, s, field) (!has_32bit_shinfo(d) ? \
- (void *)&(s)->native.field : \
- (void *)&(s)->compat.field)
-
+/*
+ * Compat field is never larger than native field, so cast to that as it
+ * is the largest memory range it is safe for the caller to modify without
+ * further discrimination between compat and native cases.
+ */
+#define __shared_info(d, s, field) \
+ (*(!has_32bit_shinfo(d) ? \
+ (typeof(&(s)->compat.field))&(s)->native.field : \
+ (typeof(&(s)->compat.field))&(s)->compat.field))
#define shared_info(d, field) \
__shared_info(d, (d)->shared_info, field)
-#define shared_info_addr(d, field) \
- __shared_info_addr(d, (d)->shared_info, field)
typedef union {
struct vcpu_info native;
struct compat_vcpu_info compat;
} vcpu_info_t;
-#define vcpu_info(v, field) (*(!has_32bit_shinfo((v)->domain) ? \
- &(v)->vcpu_info->native.field : \
- &(v)->vcpu_info->compat.field))
-#define vcpu_info_addr(v, field) (!has_32bit_shinfo((v)->domain) ? \
- (void *)&(v)->vcpu_info->native.field : \
- (void *)&(v)->vcpu_info->compat.field)
+/* As above, cast to compat field type. */
+#define vcpu_info(v, field) \
+ (*(!has_32bit_shinfo((v)->domain) ? \
+ (typeof(&(v)->vcpu_info->compat.field))&(v)->vcpu_info->native.field : \
+ (typeof(&(v)->vcpu_info->compat.field))&(v)->vcpu_info->compat.field))
#else
typedef struct shared_info shared_info_t;
-
-#define __shared_info(d, s, field) ((s)->field)
-#define __shared_info_addr(d, s, field) ((void *)&(s)->field)
-
#define shared_info(d, field) ((d)->shared_info->field)
-#define shared_info_addr(d, field) ((void *)&(d)->shared_info->field)
typedef struct vcpu_info vcpu_info_t;
-
#define vcpu_info(v, field) ((v)->vcpu_info->field)
-#define vcpu_info_addr(v, field) ((void *)&(v)->vcpu_info->field)
#endif