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

[Xen-changelog] [xen stable-4.9] gnttab: correct maptrack table accesses



commit 68e0184422d31b62730f68ed70e42c3fef8b2dc4
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Tue Jun 20 15:41:36 2017 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Jun 20 15:41:36 2017 +0200

    gnttab: correct maptrack table accesses
    
    In order to observe a consistent (limit,pointer-table) pair, the reader
    needs to either hold the maptrack lock (in line with documentation) or
    both sides need to order their accesses suitably (the writer side
    barrier was removed by commit dff515dfea ["gnttab: use per-VCPU
    maptrack free lists"], and a read side barrier has never been there).
    
    Make the writer publish a new table page before limit (for bounds
    checks to work), and new list head last (for racing maptrack_entry()
    invocations to work). At the same time add read barriers to lockless
    readers.
    
    Additionally get_maptrack_handle() must not assume ->maptrack_head to
    not change behind its back: Another handle may be put (updating only
    ->maptrack_tail) and then got or stolen (updating ->maptrack_head).
    
    This is part of XSA-218.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: George Dunlap <george.dunlap@xxxxxxxxxx>
    master commit: 4b78efa91c8ae3c42e14b8eaeaad773c5eb3b71a
    master date: 2017-06-20 14:34:34 +0200
---
 xen/common/grant_table.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c
index 7098af7..927fd2b 100644
--- a/xen/common/grant_table.c
+++ b/xen/common/grant_table.c
@@ -395,7 +395,7 @@ get_maptrack_handle(
     struct grant_table *lgt)
 {
     struct vcpu          *curr = current;
-    int                   i;
+    unsigned int          i, head;
     grant_handle_t        handle;
     struct grant_mapping *new_mt;
 
@@ -451,17 +451,20 @@ get_maptrack_handle(
         new_mt[i].ref = handle + i + 1;
         new_mt[i].vcpu = curr->vcpu_id;
     }
-    new_mt[i - 1].ref = curr->maptrack_head;
 
     /* Set tail directly if this is the first page for this VCPU. */
     if ( curr->maptrack_tail == MAPTRACK_TAIL )
         curr->maptrack_tail = handle + MAPTRACK_PER_PAGE - 1;
 
-    write_atomic(&curr->maptrack_head, handle + 1);
-
     lgt->maptrack[nr_maptrack_frames(lgt)] = new_mt;
+    smp_wmb();
     lgt->maptrack_limit += MAPTRACK_PER_PAGE;
 
+    do {
+        new_mt[i - 1].ref = read_atomic(&curr->maptrack_head);
+        head = cmpxchg(&curr->maptrack_head, new_mt[i - 1].ref, handle + 1);
+    } while ( head != new_mt[i - 1].ref );
+
     spin_unlock(&lgt->maptrack_lock);
 
     return handle;
@@ -727,6 +730,7 @@ static unsigned int mapkind(
     for ( handle = 0; !(kind & MAPKIND_WRITE) &&
                       handle < lgt->maptrack_limit; handle++ )
     {
+        smp_rmb();
         map = &maptrack_entry(lgt, handle);
         if ( !(map->flags & (GNTMAP_device_map|GNTMAP_host_map)) ||
              map->domid != rd->domain_id )
@@ -1094,6 +1098,7 @@ __gnttab_unmap_common(
         return;
     }
 
+    smp_rmb();
     map = &maptrack_entry(lgt, op->handle);
 
     grant_read_lock(lgt);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.9

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

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