[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [XEN] grant tables: update pair of entries using a union to ensure endian neutrality.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 1b85fbc8c013c76a5f66d2dcb95f0a02fed202be
# Parent  d8338b28bcd63444a819867114a57193c64951f8
[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@xxxxxxxxxxxxxx>
---
 xen/common/grant_table.c |   82 +++++++++++++++++++++++++++++------------------
 1 files changed, 51 insertions(+), 31 deletions(-)

diff -r d8338b28bcd6 -r 1b85fbc8c013 xen/common/grant_table.c
--- a/xen/common/grant_table.c  Mon Aug 14 14:44:31 2006 +0100
+++ b/xen/common/grant_table.c  Mon Aug 14 15:17:42 2006 +0100
@@ -33,6 +33,18 @@
 #include <xen/domain_page.h>
 #include <acm/acm_hooks.h>
 
+/*
+ * The first two members of a grant entry are updated as a combined pair.
+ * The following union allows that to happen in an endian-neutral fashion.
+ */
+union grant_combo {
+    uint32_t word;
+    struct {
+        uint16_t flags;
+        domid_t  domid;
+    } shorts;
+};
+
 #define PIN_FAIL(_lbl, _rc, _f, _a...)          \
     do {                                        \
         DPRINTK( _f, ## _a );                   \
@@ -178,7 +190,7 @@ __gnttab_map_grant_ref(
          */
         for ( ; ; )
         {
-            u32 scombo, prev_scombo, new_scombo;
+            union grant_combo scombo, prev_scombo, new_scombo;
 
             if ( unlikely((sflags & GTF_type_mask) != GTF_permit_access) ||
                  unlikely(sdom != led->domain->domain_id) )
@@ -187,22 +199,25 @@ __gnttab_map_grant_ref(
                          sflags, sdom, led->domain->domain_id);
 
             /* Merge two 16-bit values into a 32-bit combined update. */
-            /* NB. Endianness! */
-            scombo = ((u32)sdom << 16) | (u32)sflags;
-
-            new_scombo = scombo | GTF_reading;
+            scombo.shorts.flags = sflags;
+            scombo.shorts.domid = sdom;
+            
+            new_scombo = scombo;
+            new_scombo.shorts.flags |= GTF_reading;
+
             if ( !(op->flags & GNTMAP_readonly) )
             {
-                new_scombo |= GTF_writing;
+                new_scombo.shorts.flags |= GTF_writing;
                 if ( unlikely(sflags & GTF_readonly) )
                     PIN_FAIL(unlock_out, GNTST_general_error,
                              "Attempt to write-pin a r/o grant entry.\n");
             }
 
-            prev_scombo = cmpxchg((u32 *)&sha->flags, scombo, new_scombo);
+            prev_scombo.word = cmpxchg((u32 *)&sha->flags,
+                                       scombo.word, new_scombo.word);
 
             /* Did the combined update work (did we see what we expected?). */
-            if ( likely(prev_scombo == scombo) )
+            if ( likely(prev_scombo.word == scombo.word) )
                 break;
 
             if ( retries++ == 4 )
@@ -210,9 +225,8 @@ __gnttab_map_grant_ref(
                          "Shared grant entry is unstable.\n");
 
             /* Didn't see what we expected. Split out the seen flags & dom. */
-            /* NB. Endianness! */
-            sflags = (u16)prev_scombo;
-            sdom   = (u16)(prev_scombo >> 16);
+            sflags = prev_scombo.shorts.flags;
+            sdom   = prev_scombo.shorts.domid;
         }
 
         if ( !act->pin )
@@ -533,7 +547,7 @@ gnttab_prepare_for_transfer(
     struct grant_entry *sha;
     domid_t             sdom;
     u16                 sflags;
-    u32                 scombo, prev_scombo;
+    union grant_combo   scombo, prev_scombo, tmp_scombo;
     int                 retries = 0;
 
     if ( unlikely((rgt = rd->grant_table) == NULL) ||
@@ -562,14 +576,16 @@ gnttab_prepare_for_transfer(
         }
 
         /* Merge two 16-bit values into a 32-bit combined update. */
-        /* NB. Endianness! */
-        scombo = ((u32)sdom << 16) | (u32)sflags;
-
-        prev_scombo = cmpxchg((u32 *)&sha->flags, scombo,
-                              scombo | GTF_transfer_committed);
+        scombo.shorts.flags = sflags;
+        scombo.shorts.domid = sdom;
+
+        tmp_scombo = scombo;
+        tmp_scombo.shorts.flags |= GTF_transfer_committed;
+        prev_scombo.word = cmpxchg((u32 *)&sha->flags,
+                                   scombo.word, tmp_scombo.word);
 
         /* Did the combined update work (did we see what we expected?). */
-        if ( likely(prev_scombo == scombo) )
+        if ( likely(prev_scombo.word == scombo.word) )
             break;
 
         if ( retries++ == 4 )
@@ -579,9 +595,8 @@ gnttab_prepare_for_transfer(
         }
 
         /* Didn't see what we expected. Split out the seen flags & dom. */
-        /* NB. Endianness! */
-        sflags = (u16)prev_scombo;
-        sdom   = (u16)(prev_scombo >> 16);
+        sflags = prev_scombo.shorts.flags;
+        sdom   = prev_scombo.shorts.domid;
     }
 
     spin_unlock(&rgt->lock);
@@ -764,33 +779,38 @@ __acquire_grant_for_copy(
 
         for ( ; ; )
         {
-            u32 scombo;
-            u32 prev_scombo;
-            u32 new_scombo;
+            union grant_combo scombo, prev_scombo, new_scombo;
 
             if ( unlikely((sflags & GTF_type_mask) != GTF_permit_access ||
                           sdom != current->domain->domain_id ) )
                 PIN_FAIL(unlock_out, GNTST_general_error,
                          "Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
                          sflags, sdom, current->domain->domain_id);
-            scombo = ((u32)sdom << 16) | (u32)sflags;
-            new_scombo = scombo | GTF_reading;
+
+            /* Merge two 16-bit values into a 32-bit combined update. */
+            scombo.shorts.flags = sflags;
+            scombo.shorts.domid = sdom;
+            
+            new_scombo = scombo;
+            new_scombo.shorts.flags |= GTF_reading;
+
             if ( !readonly )
             {
-                new_scombo |= GTF_writing;
+                new_scombo.shorts.flags |= GTF_writing;
                 if ( unlikely(sflags & GTF_readonly) )
                     PIN_FAIL(unlock_out, GNTST_general_error,
                              "Attempt to write-pin a r/o grant entry.\n");
             }
-            prev_scombo = cmpxchg((u32 *)&sha->flags, scombo, new_scombo);
-            if ( likely(prev_scombo == scombo) )
+            prev_scombo.word = cmpxchg((u32 *)&sha->flags,
+                                       scombo.word, new_scombo.word);
+            if ( likely(prev_scombo.word == scombo.word) )
                 break;
 
             if ( retries++ == 4 )
                 PIN_FAIL(unlock_out, GNTST_general_error,
                          "Shared grant entry is unstable.\n");
-            sflags = (u16)prev_scombo;
-            sdom = (u16)(prev_scombo >> 16);
+            sflags = prev_scombo.shorts.flags;
+            sdom = prev_scombo.shorts.flags;
         }
 
         if ( !act->pin )

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.