WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] Fix rcu domain locking for transitive gra

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] Fix rcu domain locking for transitive grants
From: Xen patchbot-unstable <patchbot@xxxxxxx>
Date: Thu, 10 Mar 2011 22:20:16 +0000
Delivery-date: Thu, 10 Mar 2011 14:26:59 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir@xxxxxxx>
# Date 1299601830 0
# Node ID 299ed79acecfe27d20ed2ac4cb959e3c5547fd2d
# Parent  22eb31eb688ad156f0004f669b389250b5e75bfb
Fix rcu domain locking for transitive grants

When acquiring a transitive grant for copy then the owning domain
needs to be locked down as well as the granting domain. This was being
done, but the unlocking was not. The acquire code now stores the
struct domain * of the owning domain (rather than the domid) in the
active entry in the granting domain. The release code then does the
unlock on the owning domain.  Note that I believe I also fixed a bug
where, for non-transitive grants the active entry contained a
reference to the acquiring domain rather than the granting
domain. From my reading of the code this would stop the release code
for transitive grants from terminating its recursion correctly.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---


diff -r 22eb31eb688a -r 299ed79acecf xen/common/grant_table.c
--- a/xen/common/grant_table.c  Tue Mar 08 16:14:55 2011 +0000
+++ b/xen/common/grant_table.c  Tue Mar 08 16:30:30 2011 +0000
@@ -1626,11 +1626,10 @@
     struct active_grant_entry *act;
     unsigned long r_frame;
     uint16_t *status;
-    domid_t trans_domid;
     grant_ref_t trans_gref;
     int released_read;
     int released_write;
-    struct domain *trans_dom;
+    struct domain *td;
 
     released_read = 0;
     released_write = 0;
@@ -1644,15 +1643,13 @@
     if (rd->grant_table->gt_version == 1)
     {
         status = &sha->flags;
-        trans_domid = rd->domain_id;
-        /* Shut the compiler up.  This'll never be used, because
-           trans_domid == rd->domain_id, but gcc doesn't know that. */
-        trans_gref = 0x1234567;
+        td = rd;
+        trans_gref = gref;
     }
     else
     {
         status = &status_entry(rd->grant_table, gref);
-        trans_domid = act->trans_dom;
+        td = act->trans_domain;
         trans_gref = act->trans_gref;
     }
 
@@ -1680,21 +1677,16 @@
 
     spin_unlock(&rd->grant_table->lock);
 
-    if ( trans_domid != rd->domain_id )
+    if ( td != rd )
     {
-        if ( released_write || released_read )
-        {
-            trans_dom = rcu_lock_domain_by_id(trans_domid);
-            if ( trans_dom != NULL )
-            {
-                /* Recursive calls, but they're tail calls, so it's
-                   okay. */
-                if ( released_write )
-                    __release_grant_for_copy(trans_dom, trans_gref, 0);
-                else if ( released_read )
-                    __release_grant_for_copy(trans_dom, trans_gref, 1);
-            }
-        }
+        /* Recursive calls, but they're tail calls, so it's
+           okay. */
+        if ( released_write )
+            __release_grant_for_copy(td, trans_gref, 0);
+        else if ( released_read )
+            __release_grant_for_copy(td, trans_gref, 1);
+
+       rcu_unlock_domain(td);
     }
 }
 
@@ -1731,7 +1723,7 @@
     uint32_t old_pin;
     domid_t trans_domid;
     grant_ref_t trans_gref;
-    struct domain *rrd;
+    struct domain *td;
     unsigned long gfn;
     unsigned long grant_frame;
     unsigned trans_page_off;
@@ -1785,8 +1777,8 @@
                                status) ) != GNTST_okay )
              goto unlock_out;
 
-        trans_domid = ld->domain_id;
-        trans_gref = 0;
+        td = rd;
+        trans_gref = gref;
         if ( sha2 && (shah->flags & GTF_type_mask) == GTF_transitive )
         {
             if ( !allow_transitive )
@@ -1808,14 +1800,15 @@
                that you don't need to go out of your way to avoid it
                in the guest. */
 
-            rrd = rcu_lock_domain_by_id(trans_domid);
-            if ( rrd == NULL )
+            /* We need to leave the rrd locked during the grant copy */
+            td = rcu_lock_domain_by_id(trans_domid);
+            if ( td == NULL )
                 PIN_FAIL(unlock_out, GNTST_general_error,
                          "transitive grant referenced bad domain %d\n",
                          trans_domid);
             spin_unlock(&rd->grant_table->lock);
 
-            rc = __acquire_grant_for_copy(rrd, trans_gref, rd,
+            rc = __acquire_grant_for_copy(td, trans_gref, rd,
                                           readonly, &grant_frame,
                                           &trans_page_off, &trans_length,
                                           0, &ignore);
@@ -1823,6 +1816,7 @@
             spin_lock(&rd->grant_table->lock);
             if ( rc != GNTST_okay ) {
                 __fixup_status_for_pin(act, status);
+               rcu_unlock_domain(td);
                 spin_unlock(&rd->grant_table->lock);
                 return rc;
             }
@@ -1834,6 +1828,7 @@
             if ( act->pin != old_pin )
             {
                 __fixup_status_for_pin(act, status);
+               rcu_unlock_domain(td);
                 spin_unlock(&rd->grant_table->lock);
                 return __acquire_grant_for_copy(rd, gref, ld, readonly,
                                                 frame, page_off, length,
@@ -1845,7 +1840,7 @@
                sub-page, but we always treat it as one because that
                blocks mappings of transitive grants. */
             is_sub_page = 1;
-            *owning_domain = rrd;
+            *owning_domain = td;
             act->gfn = -1ul;
         }
         else if ( sha1 )
@@ -1891,7 +1886,7 @@
             act->is_sub_page = is_sub_page;
             act->start = trans_page_off;
             act->length = trans_length;
-            act->trans_dom = trans_domid;
+            act->trans_domain = td;
             act->trans_gref = trans_gref;
             act->frame = grant_frame;
         }
diff -r 22eb31eb688a -r 299ed79acecf xen/include/xen/grant_table.h
--- a/xen/include/xen/grant_table.h     Tue Mar 08 16:14:55 2011 +0000
+++ b/xen/include/xen/grant_table.h     Tue Mar 08 16:30:30 2011 +0000
@@ -32,7 +32,7 @@
 struct active_grant_entry {
     u32           pin;    /* Reference count information.             */
     domid_t       domid;  /* Domain being granted access.             */
-    domid_t       trans_dom;
+    struct domain *trans_domain;
     uint32_t      trans_gref;
     unsigned long frame;  /* Frame being granted.                     */
     unsigned long gfn;    /* Guest's idea of the frame being granted. */

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] Fix rcu domain locking for transitive grants, Xen patchbot-unstable <=