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

[xen staging] x86/domain: Fix domlist_insert() updating the domain hash



commit 36f75d39b38d94a0d17119a4178c08de994ead23
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Wed Jul 31 20:05:21 2024 +0100
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Wed Jul 31 23:19:42 2024 +0100

    x86/domain: Fix domlist_insert() updating the domain hash
    
    A last minute review request was to dedup the expression calculating the
    domain hash bucket.
    
    While the code reads correctly, it is buggy because rcu_assign_pointer() is 
a
    deeply misleading API assigning by name not value, and - contrary to it's 
name
    - does not hide an indirection.
    
    Therefore, rcu_assign_pointer(bucket, d); updates the local bucket variable 
on
    the stack, not domain_hash[], causing all subsequent domid lookups to fail.
    
    Rework the logic to use pd in the same way that domlist_remove() does.
    
    Fixes: 19995bc70cc6 ("xen/domain: Factor domlist_{insert,remove}() out of 
domain_{create,destroy}()")
    Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
---
 xen/common/domain.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/xen/common/domain.c b/xen/common/domain.c
index 8d8f40ccb2..92263a4fbd 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -70,7 +70,7 @@ struct domain *domain_list;
  */
 static void domlist_insert(struct domain *d)
 {
-    struct domain **pd, *bucket;
+    struct domain **pd;
 
     spin_lock(&domlist_update_lock);
 
@@ -79,12 +79,12 @@ static void domlist_insert(struct domain *d)
         if ( (*pd)->domain_id > d->domain_id )
             break;
 
-    bucket = domain_hash[DOMAIN_HASH(d->domain_id)];
-
     d->next_in_list = *pd;
-    d->next_in_hashbucket = bucket;
     rcu_assign_pointer(*pd, d);
-    rcu_assign_pointer(bucket, d);
+
+    pd = &domain_hash[DOMAIN_HASH(d->domain_id)];
+    d->next_in_hashbucket = *pd;
+    rcu_assign_pointer(*pd, d);
 
     spin_unlock(&domlist_update_lock);
 }
--
generated by git-patchbot for /home/xen/git/xen.git#staging



 


Rackspace

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