ia64/xen-unstable

changeset 11106:1b85fbc8c013

[XEN] grant tables: update pair of entries using a union to ensure endian neutrality.

The first two members of a grant entry are updated as a combined pair.
The following patch uses a union so updates can happen in an endian neutral fashion.

Signed-off-by: Jimi Xenidis <jimix@watson.ibm.com>
author kfraser@localhost.localdomain
date Mon Aug 14 15:17:42 2006 +0100 (2006-08-14)
parents d8338b28bcd6
children 6b6bfa60707e
files xen/common/grant_table.c
line diff
     1.1 --- a/xen/common/grant_table.c	Mon Aug 14 14:44:31 2006 +0100
     1.2 +++ b/xen/common/grant_table.c	Mon Aug 14 15:17:42 2006 +0100
     1.3 @@ -33,6 +33,18 @@
     1.4  #include <xen/domain_page.h>
     1.5  #include <acm/acm_hooks.h>
     1.6  
     1.7 +/*
     1.8 + * The first two members of a grant entry are updated as a combined pair.
     1.9 + * The following union allows that to happen in an endian-neutral fashion.
    1.10 + */
    1.11 +union grant_combo {
    1.12 +    uint32_t word;
    1.13 +    struct {
    1.14 +        uint16_t flags;
    1.15 +        domid_t  domid;
    1.16 +    } shorts;
    1.17 +};
    1.18 +
    1.19  #define PIN_FAIL(_lbl, _rc, _f, _a...)          \
    1.20      do {                                        \
    1.21          DPRINTK( _f, ## _a );                   \
    1.22 @@ -178,7 +190,7 @@ static void
    1.23           */
    1.24          for ( ; ; )
    1.25          {
    1.26 -            u32 scombo, prev_scombo, new_scombo;
    1.27 +            union grant_combo scombo, prev_scombo, new_scombo;
    1.28  
    1.29              if ( unlikely((sflags & GTF_type_mask) != GTF_permit_access) ||
    1.30                   unlikely(sdom != led->domain->domain_id) )
    1.31 @@ -187,22 +199,25 @@ static void
    1.32                           sflags, sdom, led->domain->domain_id);
    1.33  
    1.34              /* Merge two 16-bit values into a 32-bit combined update. */
    1.35 -            /* NB. Endianness! */
    1.36 -            scombo = ((u32)sdom << 16) | (u32)sflags;
    1.37 +            scombo.shorts.flags = sflags;
    1.38 +            scombo.shorts.domid = sdom;
    1.39 +            
    1.40 +            new_scombo = scombo;
    1.41 +            new_scombo.shorts.flags |= GTF_reading;
    1.42  
    1.43 -            new_scombo = scombo | GTF_reading;
    1.44              if ( !(op->flags & GNTMAP_readonly) )
    1.45              {
    1.46 -                new_scombo |= GTF_writing;
    1.47 +                new_scombo.shorts.flags |= GTF_writing;
    1.48                  if ( unlikely(sflags & GTF_readonly) )
    1.49                      PIN_FAIL(unlock_out, GNTST_general_error,
    1.50                               "Attempt to write-pin a r/o grant entry.\n");
    1.51              }
    1.52  
    1.53 -            prev_scombo = cmpxchg((u32 *)&sha->flags, scombo, new_scombo);
    1.54 +            prev_scombo.word = cmpxchg((u32 *)&sha->flags,
    1.55 +                                       scombo.word, new_scombo.word);
    1.56  
    1.57              /* Did the combined update work (did we see what we expected?). */
    1.58 -            if ( likely(prev_scombo == scombo) )
    1.59 +            if ( likely(prev_scombo.word == scombo.word) )
    1.60                  break;
    1.61  
    1.62              if ( retries++ == 4 )
    1.63 @@ -210,9 +225,8 @@ static void
    1.64                           "Shared grant entry is unstable.\n");
    1.65  
    1.66              /* Didn't see what we expected. Split out the seen flags & dom. */
    1.67 -            /* NB. Endianness! */
    1.68 -            sflags = (u16)prev_scombo;
    1.69 -            sdom   = (u16)(prev_scombo >> 16);
    1.70 +            sflags = prev_scombo.shorts.flags;
    1.71 +            sdom   = prev_scombo.shorts.domid;
    1.72          }
    1.73  
    1.74          if ( !act->pin )
    1.75 @@ -533,7 +547,7 @@ gnttab_prepare_for_transfer(
    1.76      struct grant_entry *sha;
    1.77      domid_t             sdom;
    1.78      u16                 sflags;
    1.79 -    u32                 scombo, prev_scombo;
    1.80 +    union grant_combo   scombo, prev_scombo, tmp_scombo;
    1.81      int                 retries = 0;
    1.82  
    1.83      if ( unlikely((rgt = rd->grant_table) == NULL) ||
    1.84 @@ -562,14 +576,16 @@ gnttab_prepare_for_transfer(
    1.85          }
    1.86  
    1.87          /* Merge two 16-bit values into a 32-bit combined update. */
    1.88 -        /* NB. Endianness! */
    1.89 -        scombo = ((u32)sdom << 16) | (u32)sflags;
    1.90 +        scombo.shorts.flags = sflags;
    1.91 +        scombo.shorts.domid = sdom;
    1.92  
    1.93 -        prev_scombo = cmpxchg((u32 *)&sha->flags, scombo,
    1.94 -                              scombo | GTF_transfer_committed);
    1.95 +        tmp_scombo = scombo;
    1.96 +        tmp_scombo.shorts.flags |= GTF_transfer_committed;
    1.97 +        prev_scombo.word = cmpxchg((u32 *)&sha->flags,
    1.98 +                                   scombo.word, tmp_scombo.word);
    1.99  
   1.100          /* Did the combined update work (did we see what we expected?). */
   1.101 -        if ( likely(prev_scombo == scombo) )
   1.102 +        if ( likely(prev_scombo.word == scombo.word) )
   1.103              break;
   1.104  
   1.105          if ( retries++ == 4 )
   1.106 @@ -579,9 +595,8 @@ gnttab_prepare_for_transfer(
   1.107          }
   1.108  
   1.109          /* Didn't see what we expected. Split out the seen flags & dom. */
   1.110 -        /* NB. Endianness! */
   1.111 -        sflags = (u16)prev_scombo;
   1.112 -        sdom   = (u16)(prev_scombo >> 16);
   1.113 +        sflags = prev_scombo.shorts.flags;
   1.114 +        sdom   = prev_scombo.shorts.domid;
   1.115      }
   1.116  
   1.117      spin_unlock(&rgt->lock);
   1.118 @@ -764,33 +779,38 @@ static int
   1.119  
   1.120          for ( ; ; )
   1.121          {
   1.122 -            u32 scombo;
   1.123 -            u32 prev_scombo;
   1.124 -            u32 new_scombo;
   1.125 +            union grant_combo scombo, prev_scombo, new_scombo;
   1.126  
   1.127              if ( unlikely((sflags & GTF_type_mask) != GTF_permit_access ||
   1.128                            sdom != current->domain->domain_id ) )
   1.129                  PIN_FAIL(unlock_out, GNTST_general_error,
   1.130                           "Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
   1.131                           sflags, sdom, current->domain->domain_id);
   1.132 -            scombo = ((u32)sdom << 16) | (u32)sflags;
   1.133 -            new_scombo = scombo | GTF_reading;
   1.134 +
   1.135 +            /* Merge two 16-bit values into a 32-bit combined update. */
   1.136 +            scombo.shorts.flags = sflags;
   1.137 +            scombo.shorts.domid = sdom;
   1.138 +            
   1.139 +            new_scombo = scombo;
   1.140 +            new_scombo.shorts.flags |= GTF_reading;
   1.141 +
   1.142              if ( !readonly )
   1.143              {
   1.144 -                new_scombo |= GTF_writing;
   1.145 +                new_scombo.shorts.flags |= GTF_writing;
   1.146                  if ( unlikely(sflags & GTF_readonly) )
   1.147                      PIN_FAIL(unlock_out, GNTST_general_error,
   1.148                               "Attempt to write-pin a r/o grant entry.\n");
   1.149              }
   1.150 -            prev_scombo = cmpxchg((u32 *)&sha->flags, scombo, new_scombo);
   1.151 -            if ( likely(prev_scombo == scombo) )
   1.152 +            prev_scombo.word = cmpxchg((u32 *)&sha->flags,
   1.153 +                                       scombo.word, new_scombo.word);
   1.154 +            if ( likely(prev_scombo.word == scombo.word) )
   1.155                  break;
   1.156  
   1.157              if ( retries++ == 4 )
   1.158                  PIN_FAIL(unlock_out, GNTST_general_error,
   1.159                           "Shared grant entry is unstable.\n");
   1.160 -            sflags = (u16)prev_scombo;
   1.161 -            sdom = (u16)(prev_scombo >> 16);
   1.162 +            sflags = prev_scombo.shorts.flags;
   1.163 +            sdom = prev_scombo.shorts.flags;
   1.164          }
   1.165  
   1.166          if ( !act->pin )