diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-03-16 14:11:34 +0000 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-03-16 14:11:34 +0000 |
commit | 33c8483360bba3536dc678a94e7f70cb75828066 (patch) | |
tree | 96762b4f3dc117f35580f54b3c7e1d63db0b4f1d /xen/include/xen/shared.h | |
parent | 266a06100af5272c956bf7dba719b0b823647a5b (diff) | |
download | xen-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.h | 36 |
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 |